food

decompiled_code:
int __fastcall food(int a1, _DWORD *a2)
{
__int64 v3; // rbx
int v4; // esi
_DWORD *v5; // rax
int result; // eax

v3 = (__int64)&a2[2 * (a1 - 1) + 2];
while ( 1 )
{
foodx = rand() % (COLS - 2) + 1;
v4 = rand() % (LINES - 3) + 2;
foody = v4;
if ( a1 <= 0 )
break;
v5 = a2;
while ( 1 )
{
while ( *v5 != foodx )
{
v5 += 2;
if ( v5 == (_DWORD *)v3 )
goto LABEL_8;
}
if ( v4 == v5[1] )
break;
v5 += 2;
if ( v5 == (_DWORD *)v3 )
goto LABEL_8;
}
}
LABEL_8:
result = wmove(stdscr, v4, foodx);
if ( result != -1 )
result = waddch(stdscr, 0x40uLL);
return result;
}

canonical_decompiled_code:
int __fastcall func4(int a1, _DWORD *a2)
{
__int64 v3; // rbx
int v4; // esi
_DWORD *v5; // rax
int result; // eax

v3 = (__int64)&a2[2 * (a1 - 1) + 2];
while ( 1 )
{
foodx = rand() % (COLS - 2) + 1;
v4 = rand() % (LINES - 3) + 2;
foody = v4;
if ( a1 <= 0 )
break;
v5 = a2;
while ( 1 )
{
while ( *v5 != foodx )
{
v5 += 2;
if ( v5 == (_DWORD *)v3 )
goto LABEL_8;
}
if ( v4 == v5[1] )
break;
v5 += 2;
if ( v5 == (_DWORD *)v3 )
goto LABEL_8;
}
}
LABEL_8:
result = wmove(stdscr, v4, foodx);
if ( result != -1 )
result = waddch(stdscr, 0x40uLL);
return result;
}

original_code:
void food(int count, snake *s) {
 int i;
 int flag;
 char food_body = '@';
 while(1) {
  flag = 0;
  foodx = rand() % (COLS-2) + 1;
  foody = rand() % (LINES-3) + 2;
  for(i=0; i<count; i++) {
   if(s[i].x==foodx && s[i].y==foody) {
    flag = 1;
    break;
   }
  }
  if(!flag) break;
 }
 (wmove((stdscr),((foody)),((foodx))) == (-1) ? (-1) : waddch((stdscr),((food_body))));
}

canonical_original_code:
void food(int count, struct snake *s) {
 int i;
 int flag;
 char food_body = '@';
 while(1) {
  flag = 0;
  foodx = rand() % (COLS-2) + 1;
  foody = rand() % (LINES-3) + 2;
  for(i=0; i<count; i++) {
   if(s[i].x==foodx && s[i].y==foody) {
    flag = 1;
    break;
   }
  }
  if(!flag) break;
 }
 (wmove((stdscr),((foody)),((foodx))) == (-1) ? (-1) : waddch((stdscr),((food_body))));
}

variable_types: count int

variable_types:
s
struct snake { int x; int y; } *

variable_types: i int

variable_types: flag int


impact

repo: slacknux/cSnake

decompiled_code:
__int64 __fastcall impact(int a1, unsigned int a2, _DWORD *a3)
{
__int64 v5; // rcx
int *v6; // rsi
int v7; // edx
int v8; // esi
_DWORD *v9; // rax
__int64 v10; // rcx
__int64 result; // rax

v5 = 2LL * a1;
v6 = &a3[v5 - 2];
v7 = *v6;
if ( !*v6 || v7 == COLS - 1 || (v8 = v6[1], v8 == 1) || v8 == LINES - 1 )
{
LABEL_10:
put_high_score(score_0, a2);
return 1LL;
}
if ( a1 > 4 )
{
v9 = &a3[v5];
v10 = (__int64)&a3[v5 - 2 + -2 * (unsigned int)(a1 - 5)];
while ( v7 != *(v9 - 10) || v8 != *(v9 - 9) )
{
v9 -= 2;
if ( v9 == (_DWORD *)v10 )
goto LABEL_12;
}
goto LABEL_10;
}
LABEL_12:
if ( v7 == foodx && v8 == foody )
{
ate = 1;
score_0 += 10;
mvprintw(0, 0, "score: %d", (unsigned int)score_0);
food(a1, a3);
result = (unsigned int)(score_0 % 100);
if ( score_0 % 100 )
{
result = 0LL;
}
else if ( (int)speed > 10000 )
{
speed -= 10000;
}
}
else
{
ate = 0;
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func5(int a1, unsigned int a2, _DWORD *a3)
{
__int64 v5; // rcx
int *v6; // rsi
int v7; // edx
int v8; // esi
_DWORD *v9; // rax
__int64 v10; // rcx
__int64 result; // rax

v5 = 2LL * a1;
v6 = &a3[v5 - 2];
v7 = *v6;
if ( !*v6 || v7 == COLS - 1 || (v8 = v6[1], v8 == 1) || v8 == LINES - 1 )
{
LABEL_10:
func3(score_0, a2);
return 1LL;
}
if ( a1 > 4 )
{
v9 = &a3[v5];
v10 = (__int64)&a3[v5 - 2 + -2 * (unsigned int)(a1 - 5)];
while ( v7 != *(v9 - 10) || v8 != *(v9 - 9) )
{
v9 -= 2;
if ( v9 == (_DWORD *)v10 )
goto LABEL_12;
}
goto LABEL_10;
}
LABEL_12:
if ( v7 == foodx && v8 == foody )
{
ate = 1;
score_0 += 10;
mvprintw(0, 0, "score: %d", (unsigned int)score_0);
func4(a1, a3);
result = (unsigned int)(score_0 % 100);
if ( score_0 % 100 )
{
result = 0LL;
}
else if ( (int)speed > 10000 )
{
speed -= 10000;
}
}
else
{
ate = 0;
result = 0LL;
}
return result;
}

original_code:
int impact(int count, int level, snake *s) {
 int i;
 static int score = 0;
 if(s[count-1].x==0 || s[count-1].x==COLS-1 || s[count-1].y==1 || s[count-1].y==LINES-1) {
  put_high_score((int)score, level);
  return 1;
 }
 for(i=count-5; i>=0; i--) {
  if(s[count-1].x==s[i].x && s[count-1].y==s[i].y) {
   put_high_score((int)score, level);
   return 1;
  }
 }
 if(s[count-1].x==foodx && s[count-1].y==foody) {
  ate = 1;
  score += 10;
  mvprintw(0, 0, "score: %d", score);
  food(count, s);
  if((score%100) == 0) {
   if(speed > 10000)
    speed -= 10000;
  }
 }
 else ate = 0;
 return 0;
}

canonical_original_code:
int impact(int count, int level, struct snake *s) {
 int i;
 static int score = 0;
 if(s[count-1].x==0 || s[count-1].x==COLS-1 || s[count-1].y==1 || s[count-1].y==LINES-1) {
  put_high_score((int)score, level);
  return 1;
 }
 for(i=count-5; i>=0; i--) {
  if(s[count-1].x==s[i].x && s[count-1].y==s[i].y) {
   put_high_score((int)score, level);
   return 1;
  }
 }
 if(s[count-1].x==foodx && s[count-1].y==foody) {
  ate = 1;
  score += 10;
  mvprintw(0, 0, "score: %d", score);
  food(count, s);
  if((score%100) == 0) {
   if(speed > 10000)
    speed -= 10000;
  }
 }
 else ate = 0;
 return 0;
}

variable_types: level int

variable_types: score int

return_type: int


decompiled_code:
__int64 __fastcall shift_left(__int64 a1, int a2)
{
__int64 v2; // rdx
int v3; // eax
__int64 result; // rax

if ( a2 > 1 )
{
v2 = a1 + 8LL * (unsigned int)(a2 - 2) + 8;
do
{
v3 = *(_DWORD *)(a1 + 8);
a1 += 8LL;
*(_DWORD *)(a1 - 8) = v3;
result = *(unsigned int *)(a1 + 4);
*(_DWORD *)(a1 - 4) = result;
}
while ( a1 != v2 );
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1, int a2)
{
__int64 v2; // rdx
int v3; // eax
__int64 result; // rax

if ( a2 > 1 )
{
v2 = a1 + 8LL * (unsigned int)(a2 - 2) + 8;
do
{
v3 = *(_DWORD *)(a1 + 8);
a1 += 8LL;
*(_DWORD *)(a1 - 8) = v3;
result = *(unsigned int *)(a1 + 4);
*(_DWORD *)(a1 - 4) = result;
}
while ( a1 != v2 );
}
return result;
}

original_code:
void shift_left(snake s[], int count) {
 int i;
 for(i=0; i<count-1; i++) {
  s[i].x = s[i+1].x;
  s[i].y = s[i+1].y;
 }
}

canonical_original_code:
void shift_left(struct snake s[], int count) {
 int i;
 for(i=0; i<count-1; i++) {
  s[i].x = s[i+1].x;
  s[i].y = s[i+1].y;
 }
}

variable_types:
s
struct snake { int x; int y; } []

return_type: void


cSnake

decompiled_code:
int cSnake()
{
unsigned int v0; // er14
unsigned int v1; // er12
int *v2; // rbp
int v3; // er8
int v4; // edi
_DWORD *v5; // rdx
int v6; // eax
int v7; // ecx
int v8; // esi
int v9; // ebx
int v10; // ebx
int *v11; // rbx
unsigned int v12; // eax
char v13; // r12
int v14; // er13
int v15; // ebx
int *v16; // rax
int v17; // edx
int v18; // esi
bool v19; // cc
size_t v20; // rbx

initscr();
noecho();
curs_set(0);
keypad(stdscr, 1);
v0 = menu() - 48;
v1 = get_high_score(v0);
v2 = (int *)malloc(0x28uLL);
wclear(stdscr);
nodelay(stdscr, 1);
v3 = COLS;
v4 = LINES;
v5 = v2 + 1;
v6 = COLS / 2;
v7 = LINES / 2;
v8 = COLS / 2 + 5;
do
{
*(v5 - 1) = v6++;
v5 += 2;
*(v5 - 2) = v7;
}
while ( v8 != v6 );
if ( v3 > 0 )
{
v9 = 0;
do
{
if ( wmove(stdscr, 1, v9) != -1 )
waddch(stdscr, 0xFFFFFFDBuLL);
if ( wmove(stdscr, LINES - 1, v9) != -1 )
waddch(stdscr, 0xFFFFFFDBuLL);
++v9;
}
while ( COLS > v9 );
v4 = LINES;
}
v10 = 1;
if ( v4 > 1 )
{
do
{
if ( wmove(stdscr, v10, 0) != -1 )
waddch(stdscr, 0xFFFFFFDBuLL);
if ( wmove(stdscr, v10, COLS - 1) != -1 )
waddch(stdscr, 0xFFFFFFDBuLL);
++v10;
}
while ( LINES > v10 );
}
v11 = v2;
do
{
if ( wmove(stdscr, v11[1], *v11) != -1 )
waddch(stdscr, 0x2AuLL);
v11 += 2;
}
while ( v2 + 10 != v11 );
v12 = time(0LL);
srand(v12);
food(5, v2);
mvprintw(0, 0, "score: 0");
mvprintw(0, COLS / 2 - 4, "level: %d", v0);
mvprintw(0, COLS - 18, "high score: %d", v1);
wrefresh(stdscr);
switch ( v0 )
{
case 2u:
speed = 80000;
break;
case 3u:
speed = 50000;
break;
case 1u:
speed = 100000;
break;
}
v13 = 114;
v14 = 5;
while ( 1 )
{
v15 = wgetch(stdscr);
if ( !v15 )
break;
if ( (unsigned int)impact(v14, v0, v2) )
{
wclear(stdscr);
game_over();
wrefresh(stdscr);
break;
}
if ( v15 == 259 )
{
if ( v13 != 100 )
v13 = 117;
LABEL_34:
if ( !ate )
goto LABEL_35;
goto LABEL_50;
}
if ( v15 <= 259 )
{
switch ( v15 )
{
case 32:
nodelay(stdscr, 0);
mvprintw(0, 18, "PAUSE");
while ( wgetch(stdscr) != 32 )
;
nodelay(stdscr, 1);
mvprintw(0, 18, " ");
break;
case 258:
if ( v13 != 117 )
v13 = 100;
break;
case 27:
endwin();
free(v2);
exit(0);
}
goto LABEL_34;
}
if ( v15 == 260 )
{
if ( v13 != 114 )
v13 = 108;
goto LABEL_34;
}
if ( v15 != 261 )
goto LABEL_34;
if ( v13 != 108 )
v13 = 114;
if ( !ate )
{
LABEL_35:
mvprintw(v2[1], *v2, " ");
shift_left((__int64)v2, v14);
v16 = &v2[2 * v14 - 2];
v17 = *v16;
v18 = v16[1];
v19 = v13 <= 114;
if ( v13 == 114 )
goto LABEL_51;
goto LABEL_36;
}
LABEL_50:
v20 = 2LL * ++v14;
v2 = (int *)realloc(v2, v20 * 4);
v16 = &v2[v20 - 2];
*(_QWORD *)v16 = *(_QWORD *)&v2[v20 - 4];
v17 = *v16;
v18 = v16[1];
v19 = v13 <= 114;
if ( v13 == 114 )
{
LABEL_51:
*v16 = ++v17;
goto LABEL_40;
}
LABEL_36:
if ( v19 )
{
if ( v13 == 100 )
{
v16[1] = ++v18;
}
else if ( v13 == 108 )
{
*v16 = --v17;
}
}
else if ( v13 == 117 )
{
v16[1] = --v18;
}
LABEL_40:
if ( wmove(stdscr, v18, v17) != -1 )
waddch(stdscr, 0x2AuLL);
wrefresh(stdscr);
usleep(speed);
}
free(v2);
usleep(0x1E8480u);
return endwin();
}

canonical_decompiled_code:
int func7()
{
unsigned int v0; // er14
unsigned int v1; // er12
int *v2; // rbp
int v3; // er8
int v4; // edi
_DWORD *v5; // rdx
int v6; // eax
int v7; // ecx
int v8; // esi
int v9; // ebx
int v10; // ebx
int *v11; // rbx
unsigned int v12; // eax
char v13; // r12
int v14; // er13
int v15; // ebx
int *v16; // rax
int v17; // edx
int v18; // esi
bool v19; // cc
size_t v20; // rbx

initscr();
noecho();
curs_set(0);
keypad(stdscr, 1);
v0 = func0() - 48;
v1 = func2(v0);
v2 = (int *)malloc(0x28uLL);
wclear(stdscr);
nodelay(stdscr, 1);
v3 = COLS;
v4 = LINES;
v5 = v2 + 1;
v6 = COLS / 2;
v7 = LINES / 2;
v8 = COLS / 2 + 5;
do
{
*(v5 - 1) = v6++;
v5 += 2;
*(v5 - 2) = v7;
}
while ( v8 != v6 );
if ( v3 > 0 )
{
v9 = 0;
do
{
if ( wmove(stdscr, 1, v9) != -1 )
waddch(stdscr, 0xFFFFFFDBuLL);
if ( wmove(stdscr, LINES - 1, v9) != -1 )
waddch(stdscr, 0xFFFFFFDBuLL);
++v9;
}
while ( COLS > v9 );
v4 = LINES;
}
v10 = 1;
if ( v4 > 1 )
{
do
{
if ( wmove(stdscr, v10, 0) != -1 )
waddch(stdscr, 0xFFFFFFDBuLL);
if ( wmove(stdscr, v10, COLS - 1) != -1 )
waddch(stdscr, 0xFFFFFFDBuLL);
++v10;
}
while ( LINES > v10 );
}
v11 = v2;
do
{
if ( wmove(stdscr, v11[1], *v11) != -1 )
waddch(stdscr, 0x2AuLL);
v11 += 2;
}
while ( v2 + 10 != v11 );
v12 = time(0LL);
srand(v12);
func4(5, v2);
mvprintw(0, 0, "score: 0");
mvprintw(0, COLS / 2 - 4, "level: %d", v0);
mvprintw(0, COLS - 18, "high score: %d", v1);
wrefresh(stdscr);
switch ( v0 )
{
case 2u:
speed = 80000;
break;
case 3u:
speed = 50000;
break;
case 1u:
speed = 100000;
break;
}
v13 = 114;
v14 = 5;
while ( 1 )
{
v15 = wgetch(stdscr);
if ( !v15 )
break;
if ( (unsigned int)func5(v14, v0, v2) )
{
wclear(stdscr);
func1();
wrefresh(stdscr);
break;
}
if ( v15 == 259 )
{
if ( v13 != 100 )
v13 = 117;
LABEL_34:
if ( !ate )
goto LABEL_35;
goto LABEL_50;
}
if ( v15 <= 259 )
{
switch ( v15 )
{
case 32:
nodelay(stdscr, 0);
mvprintw(0, 18, "PAUSE");
while ( wgetch(stdscr) != 32 )
;
nodelay(stdscr, 1);
mvprintw(0, 18, " ");
break;
case 258:
if ( v13 != 117 )
v13 = 100;
break;
case 27:
endwin();
free(v2);
exit(0);
}
goto LABEL_34;
}
if ( v15 == 260 )
{
if ( v13 != 114 )
v13 = 108;
goto LABEL_34;
}
if ( v15 != 261 )
goto LABEL_34;
if ( v13 != 108 )
v13 = 114;
if ( !ate )
{
LABEL_35:
mvprintw(v2[1], *v2, " ");
func6((__int64)v2, v14);
v16 = &v2[2 * v14 - 2];
v17 = *v16;
v18 = v16[1];
v19 = v13 <= 114;
if ( v13 == 114 )
goto LABEL_51;
goto LABEL_36;
}
LABEL_50:
v20 = 2LL * ++v14;
v2 = (int *)realloc(v2, v20 * 4);
v16 = &v2[v20 - 2];
*(_QWORD *)v16 = *(_QWORD *)&v2[v20 - 4];
v17 = *v16;
v18 = v16[1];
v19 = v13 <= 114;
if ( v13 == 114 )
{
LABEL_51:
*v16 = ++v17;
goto LABEL_40;
}
LABEL_36:
if ( v19 )
{
if ( v13 == 100 )
{
v16[1] = ++v18;
}
else if ( v13 == 108 )
{
*v16 = --v17;
}
}
else if ( v13 == 117 )
{
v16[1] = --v18;
}
LABEL_40:
if ( wmove(stdscr, v18, v17) != -1 )
waddch(stdscr, 0x2AuLL);
wrefresh(stdscr);
usleep(speed);
}
free(v2);
usleep(0x1E8480u);
return endwin();
}

original_code:
void cSnake() {
 int i;
 int c = 0;
 int count = 5;
 int level = 0;
 int get_score = 0;
 char direction = 'r';
 char snake_body = '*';
 char borders_part = (char)219;
 snake *s;
 initscr();
 noecho();
 curs_set(0);
 keypad(stdscr,1);
 level = menu() - 48;
        get_score = get_high_score(level);
 s = (snake*) malloc(count * sizeof(snake));
 wclear(stdscr);
 nodelay(stdscr,1);
 for(i=0; i<count; i++) {
  s[i].y = LINES/2;
  s[i].x = (COLS/2) + i;
 }
 for(i=0; i<COLS; i++) {
  (wmove((stdscr),((1)),((i))) == (-1) ? (-1) : waddch((stdscr),((borders_part))));
  (wmove((stdscr),((LINES-1)),((i))) == (-1) ? (-1) : waddch((stdscr),((borders_part))));
 }
 for(i=1; i<LINES; i++) {
                 (wmove((stdscr),((i)),((0))) == (-1) ? (-1) : waddch((stdscr),((borders_part))));
                 (wmove((stdscr),((i)),((COLS-1))) == (-1) ? (-1) : waddch((stdscr),((borders_part))));
         }
 for(i=0; i<count; i++) {
   (wmove((stdscr),((s[i].y)),((s[i].x))) == (-1) ? (-1) : waddch((stdscr),((snake_body))));
 }
 srand(time(((void *)0)));
 food(count, s);
 mvprintw(0, 0, "score: 0");
 mvprintw(0, COLS/2-4, "level: %d", level);
 mvprintw(0, COLS-18, "high score: %d", get_score);
 wrefresh(stdscr);
 switch(level) {
  case 1: speed=100000; break;
  case 2: speed=80000; break;
  case 3: speed=50000; break;
 }
 while((c=wgetch(stdscr))) {
  if(impact(count, level, s)) {
   wclear(stdscr);
   game_over();
   wrefresh(stdscr);
   break;
  }
  switch(c) {
   case 0404:
    if(direction!='r')
     direction='l';
    break;
   case 0403:
    if(direction!='d')
     direction='u';
    break;
   case 0402:
    if(direction!='u')
     direction='d';
    break;
   case 0405:
    if(direction!='l')
     direction='r';
    break;
   case 32:
    nodelay(stdscr, 0);
    mvprintw(0, 18, "PAUSE");
    while((c=wgetch(stdscr))!=32)
     continue;
    nodelay(stdscr,1);
    mvprintw(0, 18, "     ");
    break;
   case 27:
    endwin();
    free(s);
    exit(0);
    break;
  }
  if(!ate) {
   mvprintw(s[0].y, s[0].x, " ");
   shift_left(s, count);
  }
  else {
   count++;
   s = (snake*) realloc(s, count * sizeof(snake));
   s[count-1] = s[count-2];
  }
  switch(direction) {
   case 'r': s[count-1].x += 1; break;
   case 'l': s[count-1].x -= 1; break;
   case 'd': s[count-1].y += 1; break;
   case 'u': s[count-1].y -= 1; break;
  }
  (wmove((stdscr),((s[count-1].y)),((s[count-1].x))) == (-1) ? (-1) : waddch((stdscr),((snake_body))));
  wrefresh(stdscr);
  usleep(speed);
 }
 free(s);
 usleep(2000000);
 endwin();
}

canonical_original_code:
void cSnake() {
 int i;
 int c = 0;
 int count = 5;
 int level = 0;
 int get_score = 0;
 char direction = 'r';
 char snake_body = '*';
 char borders_part = (char)219;
 struct snake *s;
 initscr();
 noecho();
 curs_set(0);
 keypad(stdscr,1);
 level = menu() - 48;
        get_score = get_high_score(level);
 s = (struct snake *) malloc(count * sizeof(snake));
 wclear(stdscr);
 nodelay(stdscr,1);
 for(i=0; i<count; i++) {
  s[i].y = LINES/2;
  s[i].x = (COLS/2) + i;
 }
 for(i=0; i<COLS; i++) {
  (wmove((stdscr),((1)),((i))) == (-1) ? (-1) : waddch((stdscr),((borders_part))));
  (wmove((stdscr),((LINES-1)),((i))) == (-1) ? (-1) : waddch((stdscr),((borders_part))));
 }
 for(i=1; i<LINES; i++) {
                 (wmove((stdscr),((i)),((0))) == (-1) ? (-1) : waddch((stdscr),((borders_part))));
                 (wmove((stdscr),((i)),((COLS-1))) == (-1) ? (-1) : waddch((stdscr),((borders_part))));
         }
 for(i=0; i<count; i++) {
   (wmove((stdscr),((s[i].y)),((s[i].x))) == (-1) ? (-1) : waddch((stdscr),((snake_body))));
 }
 srand(time(((void *)0)));
 food(count, s);
 mvprintw(0, 0, "score: 0");
 mvprintw(0, COLS/2-4, "level: %d", level);
 mvprintw(0, COLS-18, "high score: %d", get_score);
 wrefresh(stdscr);
 switch(level) {
  case 1: speed=100000; break;
  case 2: speed=80000; break;
  case 3: speed=50000; break;
 }
 while((c=wgetch(stdscr))) {
  if(impact(count, level, s)) {
   wclear(stdscr);
   game_over();
   wrefresh(stdscr);
   break;
  }
  switch(c) {
   case 0404:
    if(direction!='r')
     direction='l';
    break;
   case 0403:
    if(direction!='d')
     direction='u';
    break;
   case 0402:
    if(direction!='u')
     direction='d';
    break;
   case 0405:
    if(direction!='l')
     direction='r';
    break;
   case 32:
    nodelay(stdscr, 0);
    mvprintw(0, 18, "PAUSE");
    while((c=wgetch(stdscr))!=32)
     continue;
    nodelay(stdscr,1);
    mvprintw(0, 18, "     ");
    break;
   case 27:
    endwin();
    free(s);
    exit(0);
    break;
  }
  if(!ate) {
   mvprintw(s[0].y, s[0].x, " ");
   shift_left(s, count);
  }
  else {
   count++;
   s = (struct snake *) realloc(s, count * sizeof(snake));
   s[count-1] = s[count-2];
  }
  switch(direction) {
   case 'r': s[count-1].x += 1; break;
   case 'l': s[count-1].x -= 1; break;
   case 'd': s[count-1].y += 1; break;
   case 'u': s[count-1].y -= 1; break;
  }
  (wmove((stdscr),((s[count-1].y)),((s[count-1].x))) == (-1) ? (-1) : waddch((stdscr),((snake_body))));
  wrefresh(stdscr);
  usleep(speed);
 }
 free(s);
 usleep(2000000);
 endwin();
}

variable_types: c int

variable_types: direction char


repo: slallum/TAU-exercises

decompiled_code:
__int64 __fastcall next_level(_DWORD *a1, unsigned int *a2)
{
__int64 result; // rax

result = (unsigned int)*a1;
*a1 = result + 1;
if ( (_DWORD)result == a2[1] )
{
result = *a2;
*a1 = result;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(_DWORD *a1, unsigned int *a2)
{
__int64 result; // rax

result = (unsigned int)*a1;
*a1 = result + 1;
if ( (_DWORD)result == a2[1] )
{
result = *a2;
*a1 = result;
}
return result;
}

original_code:
void next_level(int* curr, int range[]) {
 *curr = (*curr + 1);
 if (*curr == range[1] + 1) {
  *curr = range[0];
 }
}

canonical_original_code:
void next_level(int *curr, int range[]) {
 *curr = (*curr + 1);
 if (*curr == range[1] + 1) {
  *curr = range[0];
 }
}

variable_types:
curr
int *

variable_types:
range
int []


decompiled_code:
_QWORD *request_board()
{
int *v0; // r13
int v1; // er12
int *v2; // rbx
int v3; // ebp
_QWORD *result; // rax
int v5; // [rsp+Ch] [rbp-2Ch]

puts("Enter the number of heaps:");
__isoc99_scanf();
if ( (unsigned int)(v5 - 1) > 0x1F )
{
puts("Error: the number of heaps must be between 1 and 32.");
result = 0LL;
}
else
{
v0 = (int *)calloc(v5, 4uLL);
puts("Enter the heap sizes:");
v1 = v5;
if ( v5 <= 0 )
{
LABEL_7:
result = malloc(0x10uLL);
*(_DWORD *)result = v1;
result[1] = v0;
}
else
{
v2 = v0;
v3 = 0;
while ( 1 )
{
++v3;
__isoc99_scanf();
if ( *v2 < 0 )
break;
v1 = v5;
++v2;
if ( v5 <= v3 )
goto LABEL_7;
}
printf("Error: the size of heap %d should be positive.\n", (unsigned int)v3);
result = 0LL;
}
}
return result;
}

canonical_decompiled_code:
_QWORD *func7()
{
int *v0; // r13
int v1; // er12
int *v2; // rbx
int v3; // ebp
_QWORD *result; // rax
int v5; // [rsp+Ch] [rbp-2Ch]

puts("Enter the number of heaps:");
__isoc99_scanf();
if ( (unsigned int)(v5 - 1) > 0x1F )
{
puts("Error: the number of heaps must be between 1 and 32.");
result = 0LL;
}
else
{
v0 = (int *)calloc(v5, 4uLL);
puts("Enter the heap sizes:");
v1 = v5;
if ( v5 <= 0 )
{
LABEL_7:
result = malloc(0x10uLL);
*(_DWORD *)result = v1;
result[1] = v0;
}
else
{
v2 = v0;
v3 = 0;
while ( 1 )
{
++v3;
__isoc99_scanf();
if ( *v2 < 0 )
break;
v1 = v5;
++v2;
if ( v5 <= v3 )
goto LABEL_7;
}
printf("Error: the size of heap %d should be positive.\n", (unsigned int)v3);
result = 0LL;
}
}
return result;
}

original_code:
Board* request_board() {
 int num_of_heaps;
 int *heaps;
 int i;
 printf("Enter the number of heaps:\n");
 scanf("%d", &num_of_heaps);
 if ((num_of_heaps < 1) || (num_of_heaps > 32)) {
  printf("Error: the number of heaps must be between 1 and 32.\n");
  return ((void *)0);
 }
 heaps = (int*) calloc(num_of_heaps, sizeof(int));
 printf("Enter the heap sizes:\n");
 for (i = 0; i < num_of_heaps; i++) {
  scanf("%d", &heaps[i]);
  if (heaps[i] < 0) {
   printf("Error: the size of heap %d should be positive.\n", i + 1);
   return ((void *)0);
  }
 }
 Board* board = (Board*) malloc(sizeof(Board));
 board->num_of_heaps = num_of_heaps;
 board->heaps = heaps;
 return board;
}

canonical_original_code:
struct Board *request_board() {
 int num_of_heaps;
 int *heaps;
 int i;
 printf("Enter the number of heaps:\n");
 scanf("%d", &num_of_heaps);
 if ((num_of_heaps < 1) || (num_of_heaps > 32)) {
  printf("Error: the number of heaps must be between 1 and 32.\n");
  return ((void *)0);
 }
 heaps = (int *) calloc(num_of_heaps, sizeof(int));
 printf("Enter the heap sizes:\n");
 for (i = 0; i < num_of_heaps; i++) {
  scanf("%d", &heaps[i]);
  if (heaps[i] < 0) {
   printf("Error: the size of heap %d should be positive.\n", i + 1);
   return ((void *)0);
  }
 }
 struct Board *board = (Board*) malloc(sizeof(Board));
 board->num_of_heaps = num_of_heaps;
 board->heaps = heaps;
 return board;
}

variable_types:
heaps
int *

variable_types: struct Board { int num_of_heaps; int *heaps; } *


decompiled_code:
__int64 __fastcall is_board_empty(__int64 a1)
{
_DWORD *v1; // rax
__int64 v2; // rdx

if ( *(int *)a1 <= 0 )
return 1LL;
v1 = *(_DWORD **)(a1 + 8);
v2 = (__int64)&v1[*(_DWORD *)a1 - 1 + 1];
while ( !*v1 )
{
if ( ++v1 == (_DWORD *)v2 )
return 1LL;
}
return 0LL;
}

original_code:
int is_board_empty(Board* current_board) {
 int i;
 for (i = 0; i < current_board->num_of_heaps; i++) {
  if (current_board->heaps[i] != 0) {
   return 0;
  }
 }
 return 1;
}

canonical_original_code:
int is_board_empty(struct Board *current_board) {
 int i;
 for (i = 0; i < current_board->num_of_heaps; i++) {
  if (current_board->heaps[i] != 0) {
   return 0;
  }
 }
 return 1;
}

user_defined_types: struct Board { int num_of_heaps; int *heaps; }


original_code:
void print_board(Board* current_board) {
 int max_heap_size = 0;
 int i, level;
 for (i = 0; i < current_board->num_of_heaps; i++) {
  if (current_board->heaps[i] > max_heap_size) {
   max_heap_size = current_board->heaps[i];
  }
 }
 for (level = max_heap_size; level > 0 ; level--) {
  if (current_board->heaps[0] >= level) printf("*");
  else printf(" ");
  for (i = 1; i < current_board->num_of_heaps; i++) {
   printf("\t");
   if (current_board->heaps[i] >= level) printf("*");
   else printf(" ");
  }
  printf("\n");
 }
}

canonical_original_code:
void print_board(struct Board *current_board) {
 int max_heap_size = 0;
 int i; int level;
 for (i = 0; i < current_board->num_of_heaps; i++) {
  if (current_board->heaps[i] > max_heap_size) {
   max_heap_size = current_board->heaps[i];
  }
 }
 for (level = max_heap_size; level > 0 ; level--) {
  if (current_board->heaps[0] >= level) printf("*");
  else printf(" ");
  for (i = 1; i < current_board->num_of_heaps; i++) {
   printf("\t");
   if (current_board->heaps[i] >= level) printf("*");
   else printf(" ");
  }
  printf("\n");
 }
}


extend

original_code:
void extend(vertex* current_node, board_t* board, int depth) {
 int i, move;
 element* current;
 vertex* child;
 linked_list* current_children;
 element* previous;
 if ((current_children = (linked_list*) calloc(1, sizeof(linked_list))) == ((void *)0)) {
  perror("Error: standard function calloc has failed");
  exit(1);
 }
 if ((previous = (element*) calloc(1, sizeof(element))) == ((void *)0)) {
  perror("Error: standard function calloc has failed");
  exit(1);
 }
 current_children->head = previous;
 current_node->children = current_children;
 for (i = 0; i < board->m; i++) {
  move = execute_move(board, board->n, i, current_node->value);
  if (move != -1) {
   if ((child = (vertex*) calloc(1, sizeof(vertex))) == ((void *)0)) {
    perror("Error: standard function calloc has failed");
    exit(1);
   }
   child->column_num = i;
   child->score = get_score(board);
   child->value = (-1)*(current_node->value);
   if ((child->score != 100000) && (child->score != -100000) && (depth-1 > 0)) {
    extend(child, board, depth - 1);
   }
   previous->node = child;
   if ((current = (element*) calloc(1, sizeof(element))) == ((void *)0)) {
    perror("Error: standard function calloc has failed");
    exit(1);
   }
   previous->next = current;
   current->prev = previous;
   previous = current;
   board->cells[move][i] = 0;
  }
 }
 current_children->tail = previous->prev;
 current_children->tail->next = ((void *)0);
}

canonical_original_code:
void extend(struct vertex_s *current_node, struct Board *board, int depth) {
 int i; int move;
 struct element_s *current;
 struct vertex_s *child;
 struct linked_list_s *current_children;
 struct element_s *previous;
 if ((current_children = (struct linked_list_s *) calloc(1, sizeof(linked_list))) == ((void *)0)) {
  perror("Error: standard function calloc has failed");
  exit(1);
 }
 if ((previous = (struct element_s *) calloc(1, sizeof(element))) == ((void *)0)) {
  perror("Error: standard function calloc has failed");
  exit(1);
 }
 current_children->head = previous;
 current_node->children = current_children;
 for (i = 0; i < board->m; i++) {
  move = execute_move(board, board->n, i, current_node->value);
  if (move != -1) {
   if ((child = (struct vertex_s *) calloc(1, sizeof(vertex))) == ((void *)0)) {
    perror("Error: standard function calloc has failed");
    exit(1);
   }
   child->column_num = i;
   child->score = get_score(board);
   child->value = (-1)*(current_node->value);
   if ((child->score != 100000) && (child->score != -100000) && (depth-1 > 0)) {
    extend(child, board, depth - 1);
   }
   previous->node = child;
   if ((current = (struct element_s *) calloc(1, sizeof(element))) == ((void *)0)) {
    perror("Error: standard function calloc has failed");
    exit(1);
   }
   previous->next = current;
   current->prev = previous;
   previous = current;
   board->cells[move][i] = 0;
  }
 }
 current_children->tail = previous->prev;
 current_children->tail->next = ((void *)0);
}

variable_types: struct vertex_s { int score; int column_num; int value; struct linked_list_s { struct element_s { struct vertex_s *node; struct element_s *next; struct element_s *prev; } *head; struct element_s *tail; } *children; } *

variable_types: struct Board { int **cells; int n; int m; int (*scoring_func)(int **, int, int); int (*make_move)(int **, int, int, int); } *

variable_types: depth int

variable_types: move int

variable_types: struct element_s { struct vertex_s { int score; int column_num; int value; struct linked_list_s { struct element_s *head; struct element_s *tail; } *children; } *node; struct element_s *next; struct element_s *prev; } *

variable_types: struct linked_list_s { struct element_s { struct vertex_s { int score; int column_num; int value; struct linked_list_s *children; } *node; struct element_s *next; struct element_s *prev; } *head; struct element_s *tail; } *


decompiled_code:
void __fastcall remove_tree(_QWORD *a1)
{
_QWORD *v2; // rdi
_QWORD *v3; // rbx
void *v4; // rdi

if ( a1 )
{
v2 = (_QWORD *)a1[2];
if ( v2 )
{
v3 = (_QWORD *)*v2;
if ( *v2 )
{
do
{
remove_tree(*v3);
v4 = v3;
v3 = (_QWORD *)v3[1];
free(v4);
}
while ( v3 );
v2 = (_QWORD *)a1[2];
}
free(v2);
}
}
free(a1);
}

canonical_decompiled_code:
void __fastcall func1(_QWORD *a1)
{
_QWORD *v2; // rdi
_QWORD *v3; // rbx
void *v4; // rdi

if ( a1 )
{
v2 = (_QWORD *)a1[2];
if ( v2 )
{
v3 = (_QWORD *)*v2;
if ( *v2 )
{
do
{
func1(*v3);
v4 = v3;
v3 = (_QWORD *)v3[1];
free(v4);
}
while ( v3 );
v2 = (_QWORD *)a1[2];
}
free(v2);
}
}
free(a1);
}

original_code:
void remove_tree(vertex* current_node) {
 element* previous;
 element* nextush;
 if ((current_node != ((void *)0)) && (current_node->children != ((void *)0))) {
  previous = current_node->children->head;
  while (previous != ((void *)0)) {
   remove_tree(previous->node);
   nextush = previous->next;
   free(previous);
   previous = nextush;
  }
  free(current_node->children);
 }
 free(current_node);
}

canonical_original_code:
void remove_tree(struct vertex_s *current_node) {
 struct element_s *previous;
 struct element_s *nextush;
 if ((current_node != ((void *)0)) && (current_node->children != ((void *)0))) {
  previous = current_node->children->head;
  while (previous != ((void *)0)) {
   remove_tree(previous->node);
   nextush = previous->next;
   free(previous);
   previous = nextush;
  }
  free(current_node->children);
 }
 free(current_node);
}

user_defined_types: struct vertex_s { int score; int column_num; int value; struct linked_list_s *children; }

user_defined_types: struct element_s { struct vertex_s *node; struct element_s *next; struct element_s *prev; }

user_defined_types: struct linked_list_s { struct element_s *head; struct element_s *tail; }


decompiled_code:
void connect4_init_board()
{
;
}

canonical_decompiled_code:
void func0()
{
;
}

original_code:
void connect4_init_board(Board* board) {
}

canonical_original_code:
void connect4_init_board(struct board_s *board) {
}

variable_types: struct board_s { int **cells; int n; int m; } *


decompiled_code:
__int64 __fastcall connect4_is_valid_move(__int64 *a1, _DWORD *a2)
{
__int64 v3; // rdi
__int64 v4; // r9
__int64 v5; // rax
__int64 v6; // r8
int v7; // edx
__int64 result; // rax

v3 = *((int *)a1 + 2);
*a2 = 0;
if ( (int)v3 <= 0 )
return 0LL;
v4 = *a1;
v5 = 0LL;
v6 = 4LL * (int)a2[1];
while ( 1 )
{
v7 = v5;
if ( *(_DWORD *)(*(_QWORD *)(v4 + 8 * v5) + v6) )
break;
v7 = ++v5;
*a2 = v5;
if ( v5 == v3 )
goto LABEL_7;
}
if ( !(_DWORD)v5 )
return 0LL;
LABEL_7:
result = 1LL;
*a2 = v7 - 1;
return result;
}

original_code:
int connect4_is_valid_move(Board *board, Move *new_move, int value) {
 new_move->i = 0;
 while ((new_move->i < board->n) && (board->cells[new_move->i][new_move->j] == 0)) {
  (new_move->i)++;
 }
 if (new_move->i != 0) {
  new_move->i--;
  return 1;
 }
 if ((new_move->i - 1) == -1) {
  return 0;
 }
 return 1;
}

canonical_original_code:
int connect4_is_valid_move(struct board_s *board, struct move_s *new_move, int value) {
 new_move->i = 0;
 while ((new_move->i < board->n) && (board->cells[new_move->i][new_move->j] == 0)) {
  (new_move->i)++;
 }
 if (new_move->i != 0) {
  new_move->i--;
  return 1;
 }
 if ((new_move->i - 1) == -1) {
  return 0;
 }
 return 1;
}

variable_types: value int

user_defined_types: struct board_s { int **cells; int n; int m; }


original_code:
int connect4_make_move(Board* board, Move* new_move, int value) {
 int old_i = new_move->i;
 new_move->i = 0;
 while ((new_move->i < board->n) && (board->cells[new_move->i][new_move->j] == 0)) {
  (new_move->i)++;
 }
 if (new_move->i == 0) {
  new_move->i = old_i;
  return -1;
 }
 (new_move->i)--;
 board->cells[new_move->i][new_move->j] = value;
 return 0;
}

canonical_original_code:
int connect4_make_move(struct board_s *board, struct move_s *new_move, int value) {
 int old_i = new_move->i;
 new_move->i = 0;
 while ((new_move->i < board->n) && (board->cells[new_move->i][new_move->j] == 0)) {
  (new_move->i)++;
 }
 if (new_move->i == 0) {
  new_move->i = old_i;
  return -1;
 }
 (new_move->i)--;
 board->cells[new_move->i][new_move->j] = value;
 return 0;
}


original_code:
Game *connect4_new_game() {
 Game *game = (Game*) malloc(sizeof(Game));
 if (game == ((void *)0)) {
  printf("ERROR: game could not be initialized.");
  return ((void *)0);
 }
 game->save_game_name = "Connect4";
 game->board = new_board(6, 7);
 game->current_player = 1;
 game->first_player_ai = -1;
 game->second_player_ai = -1;
 game->depth_range[0] = 1;
 game->depth_range[1] = 7;
 game->first_player_depth = game->depth_range[0];
 game->second_player_depth = game->depth_range[0];
 game->game_over = 0;
 game->is_valid_move = connect4_is_valid_move;
 game->make_move = connect4_make_move;
 game->won_game = connect4_won_game;
 game->init_board = connect4_init_board;
 game->get_score = connect4_get_score;
 game->tree = create_tree(game->board, connect4_get_score);
 game->tiles[0] = "c4N.bmp";
 game->tiles[1] = "c4P1.bmp";
 game->tiles[3] = "c4P2.bmp";
 game->tiles[2] = "TrophyTile.bmp";
 if ((game->tree == ((void *)0)) || (game->board == ((void *)0))) {
  return ((void *)0);
 }
 return game;
}

canonical_original_code:
struct game_s *connect4_new_game() {
 struct game_s *game = (Game*) malloc(sizeof(Game));
 if (game == ((void *)0)) {
  printf("ERROR: game could not be initialized.");
  return ((void *)0);
 }
 game->save_game_name = "Connect4";
 game->board = new_board(6, 7);
 game->current_player = 1;
 game->first_player_ai = -1;
 game->second_player_ai = -1;
 game->depth_range[0] = 1;
 game->depth_range[1] = 7;
 game->first_player_depth = game->depth_range[0];
 game->second_player_depth = game->depth_range[0];
 game->game_over = 0;
 game->is_valid_move = connect4_is_valid_move;
 game->make_move = connect4_make_move;
 game->won_game = connect4_won_game;
 game->init_board = connect4_init_board;
 game->get_score = connect4_get_score;
 game->tree = create_tree(game->board, connect4_get_score);
 game->tiles[0] = "c4N.bmp";
 game->tiles[1] = "c4P1.bmp";
 game->tiles[3] = "c4P2.bmp";
 game->tiles[2] = "TrophyTile.bmp";
 if ((game->tree == ((void *)0)) || (game->board == ((void *)0))) {
  return ((void *)0);
 }
 return game;
}

variable_types: struct game_s { struct board_s { int **cells; int n; int m; } *board; char *save_game_name; int current_player; int game_over; int first_player_ai; int second_player_ai; int first_player_depth; int second_player_depth; int depth_range[2]; void (*init_board)(struct board_s *board); int (*is_valid_move)(struct board_s *board, struct move_s { int i; int j; } *move, int value); int (*make_move)(struct board_s *board, struct move_s *new_move, int value); int (*won_game)(struct game_s *); int (*get_score)(struct board_s *board); struct minmax_tree_s { struct vertex_s { int score; struct move_s *current_move; int value; struct linked_list_s { struct element_s { struct vertex_s *node; struct element_s *next; struct element_s *prev; } *head; struct element_s *tail; } *children; } *root; } *tree; char *tiles[4]; } *

user_defined_types: struct game_s { struct board_s *board; char *save_game_name; int current_player; int game_over; int first_player_ai; int second_player_ai; int first_player_depth; int second_player_depth; int depth_range[2]; void (*init_board)(struct board_s *board); int (*is_valid_move)(struct board_s *board, struct move_s *move, int value); int (*make_move)(struct board_s *board, struct move_s *new_move, int value); int (*won_game)(struct game_s *); int (*get_score)(struct board_s *board); struct minmax_tree_s *tree; char *tiles[4]; }

user_defined_types: struct minmax_tree_s { struct vertex_s *root; }

user_defined_types: struct vertex_s { int score; struct move_s *current_move; int value; struct linked_list_s *children; }


original_code:
int check_spans(Board* board, int start[2], int end[2], int dir[2]) {
 int i = start[0], j = start[1], k, result = 0;
 while ((result < 4) && (result > -4) && (i < end[0])) {
  while ((result < 4) && (result > -4) && (j < end[1])) {
   result = 0;
   for (k = 0; k < 4; k++) {
    result += board->cells[i + k * dir[0]][j + k * dir[1]];
    if ((result == 4) || (result == -4)) {
     for (k = 0; k < 4; k++) {
      board->cells[i + k * dir[0]][j + k * dir[1]] = 2;
     }
    }
   }
   j++;
  }
  j = start[1];
  i++;
 }
 return ((result == 4) || (result == -4));
}

canonical_original_code:
int check_spans(struct board_s *board, int start[2], int end[2], int dir[2]) {
 int i = start[0]; int j = start[1]; int k; int result = 0;
 while ((result < 4) && (result > -4) && (i < end[0])) {
  while ((result < 4) && (result > -4) && (j < end[1])) {
   result = 0;
   for (k = 0; k < 4; k++) {
    result += board->cells[i + k * dir[0]][j + k * dir[1]];
    if ((result == 4) || (result == -4)) {
     for (k = 0; k < 4; k++) {
      board->cells[i + k * dir[0]][j + k * dir[1]] = 2;
     }
    }
   }
   j++;
  }
  j = start[1];
  i++;
 }
 return ((result == 4) || (result == -4));
}

variable_types:
start
int [2]

variable_types:
end
int [2]

variable_types:
dir
int [2]

variable_types: i int

variable_types: j int

variable_types: k int

variable_types: result int


original_code:
int connect4_won_game(Game* game) {
 int start[2], end[2], dir[2], strike = 0;
 start[0] = 0;
 start[1] = 0;
 end[0] = game->board->n - 3;
 end[1] = game->board->m - 3;
 dir[0] = 1;
 dir[1] = 1;
 strike = check_spans(game->board, start, end, dir);
 if (!strike) {
  dir[0] = 0;
  end[0] = end[0] + 3;
  strike = check_spans(game->board, start, end, dir);
 }
 if (!strike) {
  dir[0] = 1;
  dir[1] = 0;
  end[1] = end[1] + 3;
  end[0] = end[0] - 3;
  strike = check_spans(game->board, start, end, dir);
 }
 if (!strike) {
  start[1] = 3;
  dir[1] = -1;
  strike = check_spans(game->board, start, end, dir);
 }
 if (strike) {
  game->game_over = 1;
 }
 return strike;
}

canonical_original_code:
int connect4_won_game(struct game_s *game) {
 int start[2]; int end[2]; int dir[2]; int strike = 0;
 start[0] = 0;
 start[1] = 0;
 end[0] = game->board->n - 3;
 end[1] = game->board->m - 3;
 dir[0] = 1;
 dir[1] = 1;
 strike = check_spans(game->board, start, end, dir);
 if (!strike) {
  dir[0] = 0;
  end[0] = end[0] + 3;
  strike = check_spans(game->board, start, end, dir);
 }
 if (!strike) {
  dir[0] = 1;
  dir[1] = 0;
  end[1] = end[1] + 3;
  end[0] = end[0] - 3;
  strike = check_spans(game->board, start, end, dir);
 }
 if (!strike) {
  start[1] = 3;
  dir[1] = -1;
  strike = check_spans(game->board, start, end, dir);
 }
 if (strike) {
  game->game_over = 1;
 }
 return strike;
}

variable_types: strike int


original_code:
void count_horizontal(int *spans_count, int** board, int n, int m) {
 int i, j;
 int result = 0;
 for (i = 0; i < n; i++) {
  result = board[i][0] + board[i][1] + board[i][2] + board[i][3];
  spans_count[result + 4] += 1;
  for (j = 4; j < m; j++) {
   result -= board[i][j - 4];
   result += board[i][j];
   spans_count[result + 4] += 1;
  }
 }
}

canonical_original_code:
void count_horizontal(int *spans_count, int **board, int n, int m) {
 int i; int j;
 int result = 0;
 for (i = 0; i < n; i++) {
  result = board[i][0] + board[i][1] + board[i][2] + board[i][3];
  spans_count[result + 4] += 1;
  for (j = 4; j < m; j++) {
   result -= board[i][j - 4];
   result += board[i][j];
   spans_count[result + 4] += 1;
  }
 }
}

variable_types:
board
int **

variable_types: n int

variable_types: m int


original_code:
void count_vertical(int *spans_count, int** board, int n, int m) {
 int i, j;
 int result = 0;
 for (i = 0; i < m; i++) {
  result = board[0][i] + board[1][i] + board[2][i] + board[3][i];
  spans_count[result + 4] += 1;
  for (j = 4; j < n; j++) {
   result -= board[j - 4][i];
   result += board[j][i];
   spans_count[result + 4] += 1;
  }
 }
}

canonical_original_code:
void count_vertical(int *spans_count, int **board, int n, int m) {
 int i; int j;
 int result = 0;
 for (i = 0; i < m; i++) {
  result = board[0][i] + board[1][i] + board[2][i] + board[3][i];
  spans_count[result + 4] += 1;
  for (j = 4; j < n; j++) {
   result -= board[j - 4][i];
   result += board[j][i];
   spans_count[result + 4] += 1;
  }
 }
}


original_code:
void count_diagonal(int *spans_count, int** board, int n, int m) {
 int i, j;
 int result = 0;
 for (i = 0; i < n - 3; i++) {
  for (j = 0; j < m - 3; j++) {
   result = board[i][j] + board[i+1][j+1] + board[i+2][j+2] + board[i+3][j+3];
   spans_count[result + 4] += 1;
  }
 }
 result = 0;
 for (i = 0; i < n - 3; i++) {
  for (j = 3; j < m; j++) {
   result = board[i][j] + board[i+1][j-1] + board[i+2][j-2] + board[i+3][j-3];
   spans_count[result + 4] += 1;
  }
 }
}

canonical_original_code:
void count_diagonal(int *spans_count, int **board, int n, int m) {
 int i; int j;
 int result = 0;
 for (i = 0; i < n - 3; i++) {
  for (j = 0; j < m - 3; j++) {
   result = board[i][j] + board[i+1][j+1] + board[i+2][j+2] + board[i+3][j+3];
   spans_count[result + 4] += 1;
  }
 }
 result = 0;
 for (i = 0; i < n - 3; i++) {
  for (j = 3; j < m; j++) {
   result = board[i][j] + board[i+1][j-1] + board[i+2][j-2] + board[i+3][j-3];
   spans_count[result + 4] += 1;
  }
 }
}


original_code:
int connect4_get_score(Board* board) {
 int weight[9] = { 0, -5, -2, -1, 0, 1, 2, 5, 0 };
 int spans_count[9] = { 0 };
 int i;
 int result = 0;
 count_horizontal(spans_count, board->cells, board->n, board->m);
 count_vertical(spans_count, board->cells, board->n, board->m);
 count_diagonal(spans_count, board->cells, board->n, board->m);
 if (spans_count[0] > 0) {
  return -100000;
 }
 if (spans_count[8] > 0) {
  return 100000;
 }
 for (i = 0; i < 9; i++) {
  result += weight[i] * spans_count[i];
 }
 return result;
}

canonical_original_code:
int connect4_get_score(struct board_s *board) {
 int weight[9] = { 0, -5, -2, -1, 0, 1, 2, 5, 0 };
 int spans_count[9] = { 0 };
 int i;
 int result = 0;
 count_horizontal(spans_count, board->cells, board->n, board->m);
 count_vertical(spans_count, board->cells, board->n, board->m);
 count_diagonal(spans_count, board->cells, board->n, board->m);
 if (spans_count[0] > 0) {
  return -100000;
 }
 if (spans_count[8] > 0) {
  return 100000;
 }
 for (i = 0; i < 9; i++) {
  result += weight[i] * spans_count[i];
 }
 return result;
}

variable_types:
weight
int [9]


decompiled_code:
__int64 __fastcall is_set_depth_command(__int64 a1)
{
__int64 v1; // rax
char i; // dl

v1 = 0LL;
for ( i = 115; *(_BYTE *)(a1 + v1) == i; i = byte_55D[v1] )
{
if ( ++v1 == 16 )
return 1LL;
}
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1)
{
__int64 v1; // rax
char i; // dl

v1 = 0LL;
for ( i = 115; *(_BYTE *)(a1 + v1) == i; i = byte_55D[v1] )
{
if ( ++v1 == 16 )
return 1LL;
}
return 0LL;
}

original_code:
static int is_set_depth_command(char* command_line) {
    int i;
    for (i=0; i<strlen("set_number_steps"); i++){
        if (command_line[i] != "set_number_steps"[i]) {
            return 0;
        }
    }
    return 1;
}

canonical_original_code:
static int is_set_depth_command(char *command_line) {
    int i;
    for (i=0; i<strlen("set_number_steps"); i++){
        if (command_line[i] != "set_number_steps"[i]) {
            return 0;
        }
    }
    return 1;
}


decompiled_code:
__int64 __fastcall get_depth(__int64 a1)
{
return str_to_int(a1, 17LL);
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
return str_to_int(a1, 17LL);
}

original_code:
static int get_depth(char *command_line) {
    return str_to_int(command_line, strlen("set_number_steps") + 1);
}


decompiled_code:
__int64 __fastcall validate_command(__int64 a1, __int64 a2)
{
unsigned int v2; // er12

v2 = a1;
if ( (_DWORD)a1 == 1 )
{
if ( HIDWORD(a1) )
{
if ( SHIDWORD(a1) > 7 )
{
v2 = 0;
puts("Error: cannot set number of steps - too many steps");
}
}
else
{
v2 = 0;
puts("Error: number of minimax steps must be non-zero");
}
return v2;
}
if ( (_DWORD)a1 == 3 )
{
if ( (unsigned int)(HIDWORD(a1) - 1) > 6 )
{
v2 = 0;
puts("Error: column number must be in range 1-7");
return v2;
}
if ( *(_DWORD *)(**(_QWORD **)a2 + 4 * (a1 >> 32) - 4) )
{
v2 = 0;
printf("Error: column %d is full\n", HIDWORD(a1));
return v2;
}
if ( !*(_DWORD *)(a2 + 52) )
return 1;
goto LABEL_11;
}
if ( (_DWORD)a1 )
{
if ( !*(_DWORD *)(a2 + 52) || (unsigned int)(a1 - 2) > 1 )
return 1;
LABEL_11:
v2 = 0;
puts("Error: game is over");
return v2;
}
puts("Error: command not found");
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, __int64 a2)
{
unsigned int v2; // er12

v2 = a1;
if ( (_DWORD)a1 == 1 )
{
if ( HIDWORD(a1) )
{
if ( SHIDWORD(a1) > 7 )
{
v2 = 0;
puts("Error: cannot set number of steps - too many steps");
}
}
else
{
v2 = 0;
puts("Error: number of minimax steps must be non-zero");
}
return v2;
}
if ( (_DWORD)a1 == 3 )
{
if ( (unsigned int)(HIDWORD(a1) - 1) > 6 )
{
v2 = 0;
puts("Error: column number must be in range 1-7");
return v2;
}
if ( *(_DWORD *)(**(_QWORD **)a2 + 4 * (a1 >> 32) - 4) )
{
v2 = 0;
printf("Error: column %d is full\n", HIDWORD(a1));
return v2;
}
if ( !*(_DWORD *)(a2 + 52) )
return 1;
goto LABEL_11;
}
if ( (_DWORD)a1 )
{
if ( !*(_DWORD *)(a2 + 52) || (unsigned int)(a1 - 2) > 1 )
return 1;
LABEL_11:
v2 = 0;
puts("Error: game is over");
return v2;
}
puts("Error: command not found");
return 0LL;
}

original_code:
int validate_command(command_t command, game *current_game){
    if ((command.command_code == 1) && (command.arg == 0)) {
        printf("Error: number of minimax steps must be non-zero\n");
        return 0;
    }
    if (command.command_code == 3){
        if ( !( (command.arg >= 1) && (command.arg <= 7) ) ) {
            printf("Error: column number must be in range 1-7\n");
            return 0;
        }
        if (current_game->current_board.cells[0][command.arg - 1] != 0) {
            printf("Error: column %d is full\n", command.arg);
            return 0;
        }
    }
    if (command.command_code == 0) {
        printf("Error: command not found\n");
        return 0;
    }
    if ((command.command_code == 1) && (command.arg > 7)) {
        printf("Error: cannot set number of steps - too many steps\n");
        return 0;
    }
    if (current_game->game_over) {
        if (command.command_code == 3 || command.command_code == 2) {
            printf("Error: game is over\n");
            return 0;
        }
    }
    return 1;
}

canonical_original_code:
int validate_command(struct Command command, struct game_s *current_game){
    if ((command.command_code == 1) && (command.arg == 0)) {
        printf("Error: number of minimax steps must be non-zero\n");
        return 0;
    }
    if (command.command_code == 3){
        if ( !( (command.arg >= 1) && (command.arg <= 7) ) ) {
            printf("Error: column number must be in range 1-7\n");
            return 0;
        }
        if (current_game->current_board.cells[0][command.arg - 1] != 0) {
            printf("Error: column %d is full\n", command.arg);
            return 0;
        }
    }
    if (command.command_code == 0) {
        printf("Error: command not found\n");
        return 0;
    }
    if ((command.command_code == 1) && (command.arg > 7)) {
        printf("Error: cannot set number of steps - too many steps\n");
        return 0;
    }
    if (current_game->game_over) {
        if (command.command_code == 3 || command.command_code == 2) {
            printf("Error: game is over\n");
            return 0;
        }
    }
    return 1;
}

variable_types: struct Command { int command_code; int arg; }

variable_types: struct game_s { struct Board { int **cells; int n; int m; int (*scoring_func)(int **, int, int); int (*make_move)(int **, int, int, int); } current_board; int is_comp_turn; struct minmax_tree_s { struct vertex_s { int score; int column_num; int value; struct linked_list_s { struct element_s { struct vertex_s *node; struct element_s *next; struct element_s *prev; } *head; struct element_s *tail; } *children; } *root; int (*make_move)(int **, int, int, int); int (*scoring_func)(int **, int, int); } *tree; int depth; int game_over; } *

user_defined_types: struct game_s { struct Board current_board; int is_comp_turn; struct minmax_tree_s *tree; int depth; int game_over; }

user_defined_types: struct minmax_tree_s { struct vertex_s *root; int (*make_move)(int **, int, int, int); int (*scoring_func)(int **, int, int); }


decompiled_code:
__int64 __fastcall execute_command(__int64 a1, __int64 a2)
{
__int64 v2; // rbp
__int64 v3; // rdx
int v5; // eax
unsigned int v6; // er12
__int64 v7; // rdx
__int64 v8; // rcx
__int64 v9; // rdi
__int64 v10; // rcx
unsigned int v11; // eax
unsigned int v12; // er12
__int64 v13; // rdx
__int64 v14; // rcx
__int64 v15; // rax
__int64 v16; // rax

v2 = a2;
if ( (_DWORD)a1 == 5 )
{
if ( (unsigned int)new_game(a2, *(unsigned int *)(a2 + 48)) )
{
puts("Game restarted");
print_board(a2);
return 1LL;
}
return 0LL;
}
if ( (_DWORD)a1 == 4 )
{
remove_tree(**(_QWORD **)(a2 + 40));
free(*(void **)(a2 + 40));
return 0LL;
}
v3 = a1 >> 32;
if ( (_DWORD)a1 == 1 )
{
*(_DWORD *)(a2 + 48) = HIDWORD(a1);
return 1LL;
}
if ( (_DWORD)a1 != 3 )
{
if ( (_DWORD)a1 == 2 )
{
if ( !*(_QWORD *)(a2 + 40) )
{
a2 = *(unsigned int *)(a2 + 48);
v16 = create_tree(v2, a2);
*(_QWORD *)(v2 + 40) = v16;
if ( !v16 )
return 0LL;
*(_QWORD *)(v16 + 8) = &make_connect4_move;
*(_QWORD *)(v16 + 16) = &connect4_scoring;
}
v5 = get_best_move_for_player(v2, a2, v3);
if ( v5 != -1 )
{
printf("Suggested move: add disc to column %d\n", (unsigned int)(v5 + 1));
return 1LL;
}
}
return 0LL;
}
v6 = HIDWORD(a1) - 1;
execute_move(a2, 6LL, (unsigned int)(HIDWORD(a1) - 1), 1LL);
if ( (unsigned int)won_board(a2, 6LL, v7, v8) )
{
print_board(a2);
puts("Game over: you win");
*(_DWORD *)(a2 + 52) = 1;
return 1LL;
}
if ( (unsigned int)board_is_full(7LL) )
goto LABEL_27;
v9 = *(_QWORD *)(a2 + 40);
v10 = *(unsigned int *)(a2 + 48);
*(_DWORD *)(a2 + 32) = 1;
if ( v9 )
{
update_tree(v9, a2, v6, v10);
}
else
{
v15 = create_tree(a2, (unsigned int)v10);
*(_QWORD *)(a2 + 40) = v15;
if ( !v15 )
return 0LL;
*(_QWORD *)(v15 + 8) = &make_connect4_move;
*(_QWORD *)(v15 + 16) = &connect4_scoring;
}
v11 = get_computer_move(a2);
v12 = v11;
if ( v11 == -1 )
return 0LL;
printf("Computer move: add disc to column %d\n", v11 + 1);
execute_move(a2, 6LL, v12, 0xFFFFFFFFLL);
print_board(a2);
if ( !(unsigned int)won_board(a2, 6LL, v13, v14) )
{
if ( !(unsigned int)board_is_full(7LL) )
{
*(_DWORD *)(a2 + 32) = 0;
update_tree(*(_QWORD *)(a2 + 40), a2, v12, *(unsigned int *)(a2 + 48));
return 1LL;
}
LABEL_27:
print_board(a2);
puts("Game over: board is full");
*(_DWORD *)(a2 + 52) = 1;
return 1LL;
}
puts("Game over: computer wins");
*(_DWORD *)(a2 + 52) = 1;
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1, __int64 a2)
{
__int64 v2; // rbp
__int64 v3; // rdx
int v5; // eax
unsigned int v6; // er12
__int64 v7; // rdx
__int64 v8; // rcx
__int64 v9; // rdi
__int64 v10; // rcx
unsigned int v11; // eax
unsigned int v12; // er12
__int64 v13; // rdx
__int64 v14; // rcx
__int64 v15; // rax
__int64 v16; // rax

v2 = a2;
if ( (_DWORD)a1 == 5 )
{
if ( (unsigned int)new_game(a2, *(unsigned int *)(a2 + 48)) )
{
puts("Game restarted");
print_board(a2);
return 1LL;
}
return 0LL;
}
if ( (_DWORD)a1 == 4 )
{
remove_tree(**(_QWORD **)(a2 + 40));
free(*(void **)(a2 + 40));
return 0LL;
}
v3 = a1 >> 32;
if ( (_DWORD)a1 == 1 )
{
*(_DWORD *)(a2 + 48) = HIDWORD(a1);
return 1LL;
}
if ( (_DWORD)a1 != 3 )
{
if ( (_DWORD)a1 == 2 )
{
if ( !*(_QWORD *)(a2 + 40) )
{
a2 = *(unsigned int *)(a2 + 48);
v16 = create_tree(v2, a2);
*(_QWORD *)(v2 + 40) = v16;
if ( !v16 )
return 0LL;
*(_QWORD *)(v16 + 8) = &make_connect4_move;
*(_QWORD *)(v16 + 16) = &connect4_scoring;
}
v5 = get_best_move_for_player(v2, a2, v3);
if ( v5 != -1 )
{
printf("Suggested move: add disc to column %d\n", (unsigned int)(v5 + 1));
return 1LL;
}
}
return 0LL;
}
v6 = HIDWORD(a1) - 1;
execute_move(a2, 6LL, (unsigned int)(HIDWORD(a1) - 1), 1LL);
if ( (unsigned int)won_board(a2, 6LL, v7, v8) )
{
print_board(a2);
puts("Game over: you win");
*(_DWORD *)(a2 + 52) = 1;
return 1LL;
}
if ( (unsigned int)board_is_full(7LL) )
goto LABEL_27;
v9 = *(_QWORD *)(a2 + 40);
v10 = *(unsigned int *)(a2 + 48);
*(_DWORD *)(a2 + 32) = 1;
if ( v9 )
{
update_tree(v9, a2, v6, v10);
}
else
{
v15 = create_tree(a2, (unsigned int)v10);
*(_QWORD *)(a2 + 40) = v15;
if ( !v15 )
return 0LL;
*(_QWORD *)(v15 + 8) = &make_connect4_move;
*(_QWORD *)(v15 + 16) = &connect4_scoring;
}
v11 = get_computer_move(a2);
v12 = v11;
if ( v11 == -1 )
return 0LL;
printf("Computer move: add disc to column %d\n", v11 + 1);
execute_move(a2, 6LL, v12, 0xFFFFFFFFLL);
print_board(a2);
if ( !(unsigned int)won_board(a2, 6LL, v13, v14) )
{
if ( !(unsigned int)board_is_full(7LL) )
{
*(_DWORD *)(a2 + 32) = 0;
update_tree(*(_QWORD *)(a2 + 40), a2, v12, *(unsigned int *)(a2 + 48));
return 1LL;
}
LABEL_27:
print_board(a2);
puts("Game over: board is full");
*(_DWORD *)(a2 + 52) = 1;
return 1LL;
}
puts("Game over: computer wins");
*(_DWORD *)(a2 + 52) = 1;
return 1LL;
}

original_code:
int execute_command(command_t command, game *current_game) {
    int preferred_move;
    if (command.command_code == 5) {
        if ((new_game(current_game, current_game->depth)) == 0) {
            return 0;
        }
        printf("Game restarted\n");
        print_board(&(current_game->current_board));
        return 1;
    }
    if (command.command_code == 4) {
        remove_tree(current_game->tree->root);
        free(current_game->tree);
        return 0;
    }
    if (command.command_code == 1) {
        current_game->depth = command.arg;
        return 1;
    }
    if (command.command_code == 3) {
        execute_move(&(current_game->current_board), 6, command.arg - 1, 1);
        if (won_board(current_game->current_board)) {
            print_board(&(current_game->current_board));
            printf("Game over: you win\n");
            current_game->game_over = 1;
            return 1;
        }
        if (board_is_full(current_game->current_board, 7)) {
            print_board(&(current_game->current_board));
            printf("Game over: board is full\n");
            current_game->game_over = 1;
            return 1;
        }
        current_game->is_comp_turn = 1;
        if (current_game->tree == ((void *)0)) {
            if ((current_game->tree = create_tree(&(current_game->current_board), current_game->depth)) == ((void *)0)) {
                return 0;
            }
            current_game->tree->make_move = &make_connect4_move;
            current_game->tree->scoring_func = &connect4_scoring;
        } else {
            update_tree(current_game->tree, &(current_game->current_board), command.arg - 1, current_game->depth);
        }
        if ((preferred_move = get_computer_move(current_game)) == -1) {
            return 0;
        }
        printf("Computer move: add disc to column %d\n", preferred_move + 1);
        execute_move(&(current_game->current_board), 6, preferred_move, -1);
        print_board(&(current_game->current_board));
        if (won_board(current_game->current_board)) {
            printf("Game over: computer wins\n");
            current_game->game_over = 1;
            return 1;
        }
        if (board_is_full(current_game->current_board, 7)) {
            print_board(&(current_game->current_board));
            printf("Game over: board is full\n");
            current_game->game_over = 1;
            return 1;
        }
        current_game->is_comp_turn = 0;
        update_tree(current_game->tree, &(current_game->current_board), preferred_move, current_game->depth);
        return 1;
    }
    if (command.command_code == 2) {
        if (current_game->tree == ((void *)0)) {
            if ((current_game->tree = create_tree(&(current_game->current_board), current_game->depth)) == ((void *)0)) {
                return 0;
            }
            current_game->tree->make_move = &make_connect4_move;
            current_game->tree->scoring_func = &connect4_scoring;
        }
        if ((preferred_move = get_best_move_for_player(current_game)) == -1) {
            return 0;
        }
        printf("Suggested move: add disc to column %d\n", preferred_move + 1);
        return 1;
    }
    return 0;
}

canonical_original_code:
int execute_command(struct Command command, struct game_s *current_game) {
    int preferred_move;
    if (command.command_code == 5) {
        if ((new_game(current_game, current_game->depth)) == 0) {
            return 0;
        }
        printf("Game restarted\n");
        print_board(&(current_game->current_board));
        return 1;
    }
    if (command.command_code == 4) {
        remove_tree(current_game->tree->root);
        free(current_game->tree);
        return 0;
    }
    if (command.command_code == 1) {
        current_game->depth = command.arg;
        return 1;
    }
    if (command.command_code == 3) {
        execute_move(&(current_game->current_board), 6, command.arg - 1, 1);
        if (won_board(current_game->current_board)) {
            print_board(&(current_game->current_board));
            printf("Game over: you win\n");
            current_game->game_over = 1;
            return 1;
        }
        if (board_is_full(current_game->current_board, 7)) {
            print_board(&(current_game->current_board));
            printf("Game over: board is full\n");
            current_game->game_over = 1;
            return 1;
        }
        current_game->is_comp_turn = 1;
        if (current_game->tree == ((void *)0)) {
            if ((current_game->tree = create_tree(&(current_game->current_board), current_game->depth)) == ((void *)0)) {
                return 0;
            }
            current_game->tree->make_move = &make_connect4_move;
            current_game->tree->scoring_func = &connect4_scoring;
        } else {
            update_tree(current_game->tree, &(current_game->current_board), command.arg - 1, current_game->depth);
        }
        if ((preferred_move = get_computer_move(current_game)) == -1) {
            return 0;
        }
        printf("Computer move: add disc to column %d\n", preferred_move + 1);
        execute_move(&(current_game->current_board), 6, preferred_move, -1);
        print_board(&(current_game->current_board));
        if (won_board(current_game->current_board)) {
            printf("Game over: computer wins\n");
            current_game->game_over = 1;
            return 1;
        }
        if (board_is_full(current_game->current_board, 7)) {
            print_board(&(current_game->current_board));
            printf("Game over: board is full\n");
            current_game->game_over = 1;
            return 1;
        }
        current_game->is_comp_turn = 0;
        update_tree(current_game->tree, &(current_game->current_board), preferred_move, current_game->depth);
        return 1;
    }
    if (command.command_code == 2) {
        if (current_game->tree == ((void *)0)) {
            if ((current_game->tree = create_tree(&(current_game->current_board), current_game->depth)) == ((void *)0)) {
                return 0;
            }
            current_game->tree->make_move = &make_connect4_move;
            current_game->tree->scoring_func = &connect4_scoring;
        }
        if ((preferred_move = get_best_move_for_player(current_game)) == -1) {
            return 0;
        }
        printf("Suggested move: add disc to column %d\n", preferred_move + 1);
        return 1;
    }
    return 0;
}

user_defined_types: struct Command { int command_code; int arg; }

user_defined_types: struct Board { int **cells; int n; int m; int (*scoring_func)(int **, int, int); int (*make_move)(int **, int, int, int); }


decompiled_code:
void __fastcall play_game_forever(__int64 a1)
{
__int64 i; // rdi
__int64 *v3; // rax
__int64 *v4; // rbp

for ( i = get_command_line(); i; i = get_command_line() )
{
v3 = (__int64 *)parse_command_line(i);
v4 = v3;
if ( !v3 )
break;
if ( (unsigned int)validate_command(*v3, a1) && !(unsigned int)execute_command(*v4, a1) )
{
free(v4);
return;
}
free(v4);
}
}

canonical_decompiled_code:
void __fastcall func4(__int64 a1)
{
__int64 i; // rdi
__int64 *v3; // rax
__int64 *v4; // rbp

for ( i = get_command_line(); i; i = get_command_line() )
{
v3 = (__int64 *)parse_command_line(i);
v4 = v3;
if ( !v3 )
break;
if ( (unsigned int)func2(*v3, a1) && !(unsigned int)func3(*v4, a1) )
{
free(v4);
return;
}
free(v4);
}
}

original_code:
void play_game_forever(game *current_game) {
    char *command_line;
    command_t *command;
    int playing = 1;
    while (playing) {
        if ((command_line = get_command_line()) == ((void *)0)) {
            return;
        }
        if ((command = parse_command_line(command_line)) == ((void *)0)) {
            return;
        }
        if (validate_command(*command, current_game)) {
            if (execute_command(*command, current_game) == 0) {
                playing = 0;
            }
        }
  free(command);
    }
}

canonical_original_code:
void play_game_forever(struct game_s *current_game) {
    char *command_line;
    struct Command *command;
    int playing = 1;
    while (playing) {
        if ((command_line = get_command_line()) == ((void *)0)) {
            return;
        }
        if ((command = parse_command_line(command_line)) == ((void *)0)) {
            return;
        }
        if (validate_command(*command, current_game)) {
            if (execute_command(*command, current_game) == 0) {
                playing = 0;
            }
        }
  free(command);
    }
}

variable_types: struct Command { int command_code; int arg; } *

variable_types: playing int


decompiled_code:
__int64 get_first_depth()
{
__int64 v0; // rax
__int64 v1; // rdi
const char *v2; // rsi
int v3; // eax
bool v4; // cf
bool v5; // zf
const char *v6; // rdi
__int64 v7; // rcx
__int64 result; // rax

while ( 1 )
{
v0 = ((__int64 (*)(void))get_command_line)();
if ( !v0 )
break;
while ( 1 )
{
v1 = v0;
v2 = (const char *)v0;
v3 = is_set_depth_command(v0);
v4 = 0;
v5 = v3 == 0;
if ( v3 )
break;
v6 = "quit\n";
v7 = 6LL;
do
{
if ( !v7 )
break;
v4 = *v2 < (unsigned int)*v6;
v5 = *v2++ == *v6++;
--v7;
}
while ( v5 );
result = (unsigned int)(char)((!v4 && !v5) - v4);
if ( (!v4 && !v5) == v4 )
return result;
puts("Error: first command must be set_number_steps");
v0 = get_command_line("Error: first command must be set_number_steps", v2);
if ( !v0 )
return 0LL;
}
result = get_depth(v1);
if ( (_DWORD)result )
{
if ( (int)result <= 7 )
return result;
puts("Error: cannot set number of steps - too many steps");
}
else
{
puts("Error: number of minimax steps must be non-zero");
}
}
return 0LL;
}

canonical_decompiled_code:
__int64 func5()
{
__int64 v0; // rax
__int64 v1; // rdi
const char *v2; // rsi
int v3; // eax
bool v4; // cf
bool v5; // zf
const char *v6; // rdi
__int64 v7; // rcx
__int64 result; // rax

while ( 1 )
{
v0 = ((__int64 (*)(void))get_command_line)();
if ( !v0 )
break;
while ( 1 )
{
v1 = v0;
v2 = (const char *)v0;
v3 = func0(v0);
v4 = 0;
v5 = v3 == 0;
if ( v3 )
break;
v6 = "quit\n";
v7 = 6LL;
do
{
if ( !v7 )
break;
v4 = *v2 < (unsigned int)*v6;
v5 = *v2++ == *v6++;
--v7;
}
while ( v5 );
result = (unsigned int)(char)((!v4 && !v5) - v4);
if ( (!v4 && !v5) == v4 )
return result;
puts("Error: first command must be set_number_steps");
v0 = get_command_line("Error: first command must be set_number_steps", v2);
if ( !v0 )
return 0LL;
}
result = func1(v1);
if ( (_DWORD)result )
{
if ( (int)result <= 7 )
return result;
puts("Error: cannot set number of steps - too many steps");
}
else
{
puts("Error: number of minimax steps must be non-zero");
}
}
return 0LL;
}

original_code:
int get_first_depth() {
    char *command_line;
    int depth = -1;
    while (1) {
        command_line = get_command_line();
        if (command_line == ((void *)0)) {
            return 0;
        }
        if (!is_set_depth_command(command_line)) {
            if (strcmp(command_line, "quit\n") == 0) {
                return 0;
            }
            printf("Error: first command must be set_number_steps\n");
        }
        else {
            depth = get_depth(command_line);
            if (depth == 0) {
                printf("Error: number of minimax steps must be non-zero\n");
            }
            else if (depth > 7) {
                printf("Error: cannot set number of steps - too many steps\n");
            }
            else {
                return depth;
            }
        }
    }
}

variable_types: depth int


decompiled_code:
void run_interpreter()
{
void *v0; // rax
__int64 v1; // rbp
int v2; // eax

v0 = calloc(1uLL, 0x38uLL);
if ( v0 )
{
v1 = (__int64)v0;
if ( (unsigned int)new_game(v0, 0xFFFFFFFFLL) )
{
print_board(v1);
v2 = get_first_depth();
if ( v2 )
{
*(_DWORD *)(v1 + 48) = v2;
play_game_forever(v1);
free(*(void **)(v1 + 40));
free((void *)v1);
}
}
}
else
{
perror("Error: standard function malloc has failed");
}
}

canonical_decompiled_code:
void func6()
{
void *v0; // rax
__int64 v1; // rbp
int v2; // eax

v0 = calloc(1uLL, 0x38uLL);
if ( v0 )
{
v1 = (__int64)v0;
if ( (unsigned int)new_game(v0, 0xFFFFFFFFLL) )
{
print_board(v1);
v2 = func5();
if ( v2 )
{
*(_DWORD *)(v1 + 48) = v2;
func4(v1);
free(*(void **)(v1 + 40));
free((void *)v1);
}
}
}
else
{
perror("Error: standard function malloc has failed");
}
}

original_code:
void run_interpreter() {
    int depth;
    game *current_game;
    if ((current_game = (game*)calloc(1, sizeof(game))) == ((void *)0)){
        perror("Error: standard function malloc has failed");
        return;
    }
    if (new_game(current_game, -1) == 0) {
        return;
    }
    print_board(&(current_game->current_board));
    if ((depth = get_first_depth()) == 0) {
        return;
    }
    current_game->depth = depth;
    play_game_forever(current_game);
    free(current_game->tree);
    free(current_game);
    return;
}

canonical_original_code:
void run_interpreter() {
    int depth;
    struct game_s *current_game;
    if ((current_game = (struct game_s *)calloc(1, sizeof(game))) == ((void *)0)){
        perror("Error: standard function malloc has failed");
        return;
    }
    if (new_game(current_game, -1) == 0) {
        return;
    }
    print_board(&(current_game->current_board));
    if ((depth = get_first_depth()) == 0) {
        return;
    }
    current_game->depth = depth;
    play_game_forever(current_game);
    free(current_game->tree);
    free(current_game);
    return;
}


original_code:
void get_best_move(Game *game, Move *best_move) {
 int depth, max;
 depth = game->current_player == 1 ? game->first_player_depth : game->second_player_depth;
 max = game->current_player == 1;
 minmax_with_extend(game->tree->root, depth, -100000, 100000,
        max, game->board, best_move,
        game->is_valid_move, game->make_move, game->get_score);
}

canonical_original_code:
void get_best_move(struct game_s *game, struct move_s *best_move) {
 int depth; int max;
 depth = game->current_player == 1 ? game->first_player_depth : game->second_player_depth;
 max = game->current_player == 1;
 minmax_with_extend(game->tree->root, depth, -100000, 100000,
        max, game->board, best_move,
        game->is_valid_move, game->make_move, game->get_score);
}

variable_types: struct game_s { struct board_s { int **cells; int n; int m; } *board; char *save_game_name; int current_player; int game_over; int first_player_ai; int second_player_ai; int first_player_depth; int second_player_depth; int depth_range[2]; void (*init_board)(struct board_s *board); int (*is_valid_move)(struct board_s *board, struct move_s { int i; int j; } *move, int value); int (*make_move)(struct board_s *board, struct move_s *new_move, int value); int (*won_game)(struct game_s *); int (*get_score)(struct board_s *board); struct minmax_tree_s { struct vertex_s { int score; struct move_s *current_move; int value; struct linked_list_s { struct element_s { struct vertex_s *node; struct element_s *next; struct element_s *prev; } *head; struct element_s *tail; } *children; } *root; } *tree; char *tiles[4]; } *

variable_types: max int


decompiled_code:
__int64 __fastcall current_player_is_ai(_DWORD *a1)
{
__int64 result; // rax

result = (unsigned int)a1[7];
if ( a1[4] == 1 )
result = (unsigned int)a1[6];
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(_DWORD *a1)
{
__int64 result; // rax

result = (unsigned int)a1[7];
if ( a1[4] == 1 )
result = (unsigned int)a1[6];
return result;
}

original_code:
int current_player_is_ai(Game *game) {
 if (game->current_player == 1) {
  return game->first_player_ai;
 } else {
  return game->second_player_ai;
 }
}

canonical_original_code:
int current_player_is_ai(struct game_s *game) {
 if (game->current_player == 1) {
  return game->first_player_ai;
 } else {
  return game->second_player_ai;
 }
}


decompiled_code:
__int64 __fastcall handle_move(_QWORD *a1, unsigned int a2, unsigned int a3)
{
unsigned int *v4; // rax
unsigned int *v5; // rbp
__int64 v6; // rcx
__int64 result; // rax

v4 = (unsigned int *)malloc(8uLL);
if ( v4 )
{
v5 = v4;
if ( (unsigned int)current_player_is_ai(a1) )
{
get_best_move((__int64)a1, (__int64)v5);
}
else
{
*v5 = a2;
v5[1] = a3;
}
if ( ((unsigned int (__fastcall *)(_QWORD, unsigned int *, _QWORD))a1[8])(*a1, v5, *((unsigned int *)a1 + 4)) == -1 )
{
free(v5);
result = 0xFFFFFFFFLL;
}
else
{
v6 = *((unsigned int *)a1 + 9);
if ( *((_DWORD *)a1 + 4) == 1 )
v6 = *((unsigned int *)a1 + 8);
update_tree(a1[11], v5[1], *v5, v6);
free(v5);
result = 0LL;
}
}
else
{
puts("ERROR: Allocating memory for new move in handle_move.");
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(_QWORD *a1, unsigned int a2, unsigned int a3)
{
unsigned int *v4; // rax
unsigned int *v5; // rbp
__int64 v6; // rcx
__int64 result; // rax

v4 = (unsigned int *)malloc(8uLL);
if ( v4 )
{
v5 = v4;
if ( (unsigned int)func1(a1) )
{
func0((__int64)a1, (__int64)v5);
}
else
{
*v5 = a2;
v5[1] = a3;
}
if ( ((unsigned int (__fastcall *)(_QWORD, unsigned int *, _QWORD))a1[8])(*a1, v5, *((unsigned int *)a1 + 4)) == -1 )
{
free(v5);
result = 0xFFFFFFFFLL;
}
else
{
v6 = *((unsigned int *)a1 + 9);
if ( *((_DWORD *)a1 + 4) == 1 )
v6 = *((unsigned int *)a1 + 8);
update_tree(a1[11], v5[1], *v5, v6);
free(v5);
result = 0LL;
}
}
else
{
puts("ERROR: Allocating memory for new move in handle_move.");
result = 0LL;
}
return result;
}

original_code:
int handle_move(Game* game, int i, int j) {
 Move* new_move;
 if ((new_move = (Move*) malloc(sizeof(Move))) == ((void *)0)) {
  printf("ERROR: Allocating memory for new move in handle_move.\n");
  return 0;
 }
 if (current_player_is_ai(game)) {
  get_best_move(game, new_move);
 } else {
  new_move->i = i;
  new_move->j = j;
 }
 if (game->make_move(game->board, new_move, game->current_player) == -1) {
  free(new_move);
  return -1;
 }
 update_tree(game->tree, new_move->j, new_move->i, game->current_player == 1 ? game->first_player_depth : game->second_player_depth);
 free(new_move);
 return 0;
}

canonical_original_code:
int handle_move(struct game_s *game, int i, int j) {
 struct move_s *new_move;
 if ((new_move = (struct move_s *) malloc(sizeof(Move))) == ((void *)0)) {
  printf("ERROR: Allocating memory for new move in handle_move.\n");
  return 0;
 }
 if (current_player_is_ai(game)) {
  get_best_move(game, new_move);
 } else {
  new_move->i = i;
  new_move->j = j;
 }
 if (game->make_move(game->board, new_move, game->current_player) == -1) {
  free(new_move);
  return -1;
 }
 update_tree(game->tree, new_move->j, new_move->i, game->current_player == 1 ? game->first_player_depth : game->second_player_depth);
 free(new_move);
 return 0;
}


original_code:
int no_moves(Game* game, int player) {
 int i = 0, j = 0, k, l;
 int avail_move = -1;
 Move* curr_move = (Move*) malloc(sizeof(Move));
 Board* temp_board = new_board(game->board->n, game->board->m);
 if ((curr_move == ((void *)0)) || (temp_board == ((void *)0))) {
  printf("ERROR: Could not check for legal moves\n");
  return 1;
 }
 while ((avail_move == -1) && i < game->board->n) {
  while ((avail_move == -1) && j < game->board->m) {
   curr_move->i = i;
   curr_move->j = j;
   if (game->board->cells[i][j] == 0) {
    for (k = 0; k < game->board->n; k++) {
     for (l = 0; l < game->board->m; l++) {
      temp_board->cells[k][l]= game->board->cells[k][l];
     }
    }
    avail_move = game->make_move(temp_board, curr_move, player);
   }
   j++;
  }
  j = 0;
  i++;
 }
 free(curr_move);
 free_board(temp_board);
 return avail_move;
}

canonical_original_code:
int no_moves(struct game_s *game, int player) {
 int i = 0; int j = 0; int k; int l;
 int avail_move = -1;
 struct move_s *curr_move = (Move*) malloc(sizeof(Move));
 struct board_s *temp_board = new_board(game->board->n, game->board->m);
 if ((curr_move == ((void *)0)) || (temp_board == ((void *)0))) {
  printf("ERROR: Could not check for legal moves\n");
  return 1;
 }
 while ((avail_move == -1) && i < game->board->n) {
  while ((avail_move == -1) && j < game->board->m) {
   curr_move->i = i;
   curr_move->j = j;
   if (game->board->cells[i][j] == 0) {
    for (k = 0; k < game->board->n; k++) {
     for (l = 0; l < game->board->m; l++) {
      temp_board->cells[k][l]= game->board->cells[k][l];
     }
    }
    avail_move = game->make_move(temp_board, curr_move, player);
   }
   j++;
  }
  j = 0;
  i++;
 }
 free(curr_move);
 free_board(temp_board);
 return avail_move;
}

variable_types: player int

variable_types: l int

variable_types: struct board_s { int **cells; int n; int m; } *


decompiled_code:
_BOOL8 __fastcall switch_player(__int64 a1)
{
bool v1; // zf
int v2; // eax

v1 = (unsigned int)no_moves((unsigned int **)a1, -*(_DWORD *)(a1 + 16)) == 0;
v2 = *(_DWORD *)(a1 + 16);
if ( v1 )
{
v2 = -v2;
*(_DWORD *)(a1 + 16) = v2;
}
if ( v2 == 1 )
return *(_DWORD *)(a1 + 24) == 1;
if ( v2 == -1 )
return *(_DWORD *)(a1 + 28) == 1;
return 0LL;
}

original_code:
int switch_player(Game* game) {
 if (no_moves(game, game->current_player * -1) == 0) {
  game->current_player = game->current_player * (-1);
 }
 if ((game->current_player == 1) && (game->first_player_ai == 1)) {
  return 1;
 }
 if ((game->current_player == -1) && (game->second_player_ai == 1)) {
  return 1;
 }
 return 0;
}

canonical_original_code:
int switch_player(struct game_s *game) {
 if (no_moves(game, game->current_player * -1) == 0) {
  game->current_player = game->current_player * (-1);
 }
 if ((game->current_player == 1) && (game->first_player_ai == 1)) {
  return 1;
 }
 if ((game->current_player == -1) && (game->second_player_ai == 1)) {
  return 1;
 }
 return 0;
}


original_code:
int restart_game(Game *game) {
 free_board(game->board);
 game->board = new_board(game->board->n, game->board->m);
 game->current_player = 1;
 game->init_board(game->board);
 remove_tree(game->tree->root);
 free(game->tree);
 game->tree = create_tree(game->board, game->get_score);
 game->game_over = 0;
 return 1;
}

canonical_original_code:
int restart_game(struct game_s *game) {
 free_board(game->board);
 game->board = new_board(game->board->n, game->board->m);
 game->current_player = 1;
 game->init_board(game->board);
 remove_tree(game->tree->root);
 free(game->tree);
 game->tree = create_tree(game->board, game->get_score);
 game->game_over = 0;
 return 1;
}


decompiled_code:
void __fastcall free_game(void *ptr)
{
free_board(*(_QWORD *)ptr);
remove_tree(**((_QWORD **)ptr + 11));
free(*((void **)ptr + 11));
free(ptr);
}

canonical_decompiled_code:
void __fastcall func6(void *ptr)
{
free_board(*(_QWORD *)ptr);
remove_tree(**((_QWORD **)ptr + 11));
free(*((void **)ptr + 11));
free(ptr);
}

original_code:
void free_game(Game* game) {
 free_board(game->board);
 remove_tree(game->tree->root);
 free(game->tree);
 free(game);
}

canonical_original_code:
void free_game(struct game_s *game) {
 free_board(game->board);
 remove_tree(game->tree->root);
 free(game->tree);
 free(game);
}


original_code:
void copy_board(Board *source_board, Board *destination_board) {
    int i, j;
    for (i=0; i<source_board->n; i++) {
        for (j=0; j<source_board->m; j++) {
            destination_board->cells[i][j] = source_board->cells[i][j];
        }
    }
}

canonical_original_code:
void copy_board(struct board_s *source_board, struct board_s *destination_board) {
    int i; int j;
    for (i=0; i<source_board->n; i++) {
        for (j=0; j<source_board->m; j++) {
            destination_board->cells[i][j] = source_board->cells[i][j];
        }
    }
}

variable_types: i int

variable_types: j int


original_code:
int board_full(Board* board) {
 int i, j;
 for (i = 0; i < board->n; i++) {
  for (j = 0; j < board->m; j++) {
   if (board->cells[i][j] == 0) {
    return 0;
   }
  }
 }
 return 1;
}

canonical_original_code:
int board_full(struct board_s *board) {
 int i; int j;
 for (i = 0; i < board->n; i++) {
  for (j = 0; j < board->m; j++) {
   if (board->cells[i][j] == 0) {
    return 0;
   }
  }
 }
 return 1;
}


decompiled_code:
void __fastcall free_board(void *ptr)
{
__int64 v2; // rbx
void *v3; // rdi

if ( *((int *)ptr + 2) > 0 )
{
v2 = 0LL;
do
{
v3 = *(void **)(*(_QWORD *)ptr + 8 * v2++);
free(v3);
}
while ( *((_DWORD *)ptr + 2) > (int)v2 );
}
free(*(void **)ptr);
free(ptr);
}

canonical_decompiled_code:
void __fastcall func2(void *ptr)
{
__int64 v2; // rbx
void *v3; // rdi

if ( *((int *)ptr + 2) > 0 )
{
v2 = 0LL;
do
{
v3 = *(void **)(*(_QWORD *)ptr + 8 * v2++);
free(v3);
}
while ( *((_DWORD *)ptr + 2) > (int)v2 );
}
free(*(void **)ptr);
free(ptr);
}

original_code:
void free_board(Board* board) {
 int i;
 for (i = 0; i < board->n; i++) {
  free(board->cells[i]);
 }
 free(board->cells);
 free(board);
}

canonical_original_code:
void free_board(struct board_s *board) {
 int i;
 for (i = 0; i < board->n; i++) {
  free(board->cells[i]);
 }
 free(board->cells);
 free(board);
}


decompiled_code:
void ttt_init_board()
{
;
}

original_code:
void ttt_init_board(Board* board) {
}

canonical_original_code:
void ttt_init_board(struct board_s *board) {
}


decompiled_code:
_BOOL8 __fastcall ttt_is_valid_move(_QWORD *a1, int *a2)
{
return *(_DWORD *)(*(_QWORD *)(*a1 + 8LL * *a2) + 4LL * a2[1]) == 0;
}

canonical_decompiled_code:
_BOOL8 __fastcall func1(_QWORD *a1, int *a2)
{
return *(_DWORD *)(*(_QWORD *)(*a1 + 8LL * *a2) + 4LL * a2[1]) == 0;
}

original_code:
int ttt_is_valid_move(Board *board, Move *move, int value) {
 if (board->cells[move->i][move->j] != 0) {
  return 0;
 }
 return 1;
}

canonical_original_code:
int ttt_is_valid_move(struct board_s *board, struct move_s *move, int value) {
 if (board->cells[move->i][move->j] != 0) {
  return 0;
 }
 return 1;
}

variable_types:
move
struct move_s { int i; int j; } *

variable_types: value int


decompiled_code:
__int64 __fastcall ttt_make_move(_QWORD *a1, int *a2, int a3)
{
_DWORD *v3; // rcx
__int64 result; // rax

v3 = (_DWORD *)(*(_QWORD *)(*a1 + 8LL * *a2) + 4LL * a2[1]);
result = (unsigned int)*v3;
if ( (_DWORD)result )
return 0xFFFFFFFFLL;
*v3 = a3;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(_QWORD *a1, int *a2, int a3)
{
_DWORD *v3; // rcx
__int64 result; // rax

v3 = (_DWORD *)(*(_QWORD *)(*a1 + 8LL * *a2) + 4LL * a2[1]);
result = (unsigned int)*v3;
if ( (_DWORD)result )
return 0xFFFFFFFFLL;
*v3 = a3;
return result;
}

original_code:
int ttt_make_move(Board* board, Move* new_move, int value) {
 if (board->cells[new_move->i][new_move->j] != 0) {
  return -1;
 }
 board->cells[new_move->i][new_move->j] = value;
 return 0;
}

canonical_original_code:
int ttt_make_move(struct board_s *board, struct move_s *new_move, int value) {
 if (board->cells[new_move->i][new_move->j] != 0) {
  return -1;
 }
 board->cells[new_move->i][new_move->j] = value;
 return 0;
}


original_code:
Game *ttt_new_game() {
 Game *game = (Game*)malloc(sizeof(Game));
 if (game == ((void *)0)) {
  printf("ERROR: game could not be initialized.");
  return ((void *)0);
 }
 game->save_game_name = "Tic-tac-toe";
 game->board = new_board(3, 3);
 game->current_player = 1;
 game->first_player_ai = -1;
 game->second_player_ai = -1;
 game->depth_range[0] = 9;
 game->depth_range[1] = 9;
 game->first_player_depth = game->depth_range[0];
 game->second_player_depth = game->depth_range[0];
 game->game_over = 0;
 game->is_valid_move = ttt_is_valid_move;
 game->make_move = ttt_make_move;
 game->won_game = ttt_won_game;
 game->init_board = ttt_init_board;
 game->get_score = ttt_get_score;
 game->tree = create_tree(game->board, ttt_get_score);
 game->tiles[0] = "tttN.bmp";
 game->tiles[1] = "tttX.bmp";
 game->tiles[3] = "tttO.bmp";
 game->tiles[2] = "TrophyTile.bmp";
 return game;
}

canonical_original_code:
struct game_s *ttt_new_game() {
 struct game_s *game = (Game*)malloc(sizeof(Game));
 if (game == ((void *)0)) {
  printf("ERROR: game could not be initialized.");
  return ((void *)0);
 }
 game->save_game_name = "Tic-tac-toe";
 game->board = new_board(3, 3);
 game->current_player = 1;
 game->first_player_ai = -1;
 game->second_player_ai = -1;
 game->depth_range[0] = 9;
 game->depth_range[1] = 9;
 game->first_player_depth = game->depth_range[0];
 game->second_player_depth = game->depth_range[0];
 game->game_over = 0;
 game->is_valid_move = ttt_is_valid_move;
 game->make_move = ttt_make_move;
 game->won_game = ttt_won_game;
 game->init_board = ttt_init_board;
 game->get_score = ttt_get_score;
 game->tree = create_tree(game->board, ttt_get_score);
 game->tiles[0] = "tttN.bmp";
 game->tiles[1] = "tttX.bmp";
 game->tiles[3] = "tttO.bmp";
 game->tiles[2] = "TrophyTile.bmp";
 return game;
}

return_type: struct game_s { struct board_s { int **cells; int n; int m; } *board; char *save_game_name; int current_player; int game_over; int first_player_ai; int second_player_ai; int first_player_depth; int second_player_depth; int depth_range[2]; void (*init_board)(struct board_s *board); int (*is_valid_move)(struct board_s *board, struct move_s { int i; int j; } *move, int value); int (*make_move)(struct board_s *board, struct move_s *new_move, int value); int (*won_game)(struct game_s *); int (*get_score)(struct board_s *board); struct minmax_tree_s { struct vertex_s { int score; struct move_s *current_move; int value; struct linked_list_s { struct element_s { struct vertex_s *node; struct element_s *next; struct element_s *prev; } *head; struct element_s *tail; } *children; } *root; } *tree; char *tiles[4]; } *


original_code:
int check_horizontal(int i, Board* board, int value) {
 int j = 0, strike = 1, k;
 while ((strike == 1) && (j < 3)) {
  strike = strike && (board->cells[i][j] == value);
  j++;
 }
 if (strike) {
  for (k = 0; k < 3; k++) {
   board->cells[i][k] = 2;
  }
  return 1;
 } else {
  return 0;
 }
}

canonical_original_code:
int check_horizontal(int i, struct board_s *board, int value) {
 int j = 0; int strike = 1; int k;
 while ((strike == 1) && (j < 3)) {
  strike = strike && (board->cells[i][j] == value);
  j++;
 }
 if (strike) {
  for (k = 0; k < 3; k++) {
   board->cells[i][k] = 2;
  }
  return 1;
 } else {
  return 0;
 }
}

variable_types: strike int

variable_types: k int


original_code:
int check_vertical(int i, Board* board, int value) {
 int j = 0, strike = 1, k;
 while ((strike == 1) && (j < 3)) {
  strike = strike && (board->cells[j][i] == value);
  j++;
 }
 if (strike) {
  for (k = 0; k < 3; k++) {
   board->cells[k][i] = 2;
  }
  return 1;
 } else {
  return 0;
 }
}

canonical_original_code:
int check_vertical(int i, struct board_s *board, int value) {
 int j = 0; int strike = 1; int k;
 while ((strike == 1) && (j < 3)) {
  strike = strike && (board->cells[j][i] == value);
  j++;
 }
 if (strike) {
  for (k = 0; k < 3; k++) {
   board->cells[k][i] = 2;
  }
  return 1;
 } else {
  return 0;
 }
}


original_code:
int check_main_diag(Board* board, int value) {
 int i = 0, strike = 1, k;
 while ((strike == 1) && (i < 3)) {
  strike = strike && (board->cells[i][i] == value);
  i++;
 }
 if (strike) {
  for (k = 0; k < 3; k++) {
   board->cells[k][k] = 2;
  }
  return 1;
 } else {
  return 0;
 }
}

canonical_original_code:
int check_main_diag(struct board_s *board, int value) {
 int i = 0; int strike = 1; int k;
 while ((strike == 1) && (i < 3)) {
  strike = strike && (board->cells[i][i] == value);
  i++;
 }
 if (strike) {
  for (k = 0; k < 3; k++) {
   board->cells[k][k] = 2;
  }
  return 1;
 } else {
  return 0;
 }
}


original_code:
int check_sec_diag(Board* board, int value) {
 int i = 3 - 1, j = 0, k;
 int strike = 1;
 while ((strike == 1) && (i >= 0)) {
  while ((strike == 1) && (j < 3)) {
   strike = strike && (board->cells[i][j] == value);
   i--;
   j++;
  }
 }
 if (strike) {
  for (k = 0; k < 3; k++) {
   board->cells[k][3 - 1 - k] = 2;
  }
  return 1;
 } else {
  return 0;
 }
}

canonical_original_code:
int check_sec_diag(struct board_s *board, int value) {
 int i = 3 - 1; int j = 0; int k;
 int strike = 1;
 while ((strike == 1) && (i >= 0)) {
  while ((strike == 1) && (j < 3)) {
   strike = strike && (board->cells[i][j] == value);
   i--;
   j++;
  }
 }
 if (strike) {
  for (k = 0; k < 3; k++) {
   board->cells[k][3 - 1 - k] = 2;
  }
  return 1;
 } else {
  return 0;
 }
}


decompiled_code:
__int64 __fastcall ttt_won_board(_QWORD *a1)
{
int v1; // er11
int v2; // edx
int v3; // er11
int v4; // eax
__int64 result; // rax
int v6; // er11
int v7; // er11
int v8; // er11
int v9; // er11
__int64 v10[2]; // [rsp+8h] [rbp-10h]

v1 = 0;
v10[0] = 0xFFFFFFFF00000001LL;
do
{
if ( (unsigned int)check_horizontal(v1, a1, 1) || (unsigned int)check_vertical(v3, (_QWORD **)a1, v2) )
{
v4 = 1;
return *((unsigned int *)v10 + v4 - 1);
}
if ( (unsigned int)check_horizontal(v6, a1, -1) || (unsigned int)check_vertical(v7, (_QWORD **)a1, -1) )
{
v4 = 2;
return *((unsigned int *)v10 + v4 - 1);
}
v1 = v8 + 1;
}
while ( v1 != 3 );
if ( (unsigned int)check_main_diag(a1, 1) || (unsigned int)check_sec_diag(a1, 1) )
goto LABEL_11;
if ( (unsigned int)check_main_diag(a1, -1) || (result = check_sec_diag(a1, -1), (_DWORD)result) )
{
v9 = 1;
LABEL_11:
result = HIDWORD(v10[v9 - 1]);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func8(_QWORD *a1)
{
int v1; // er11
int v2; // edx
int v3; // er11
int v4; // eax
__int64 result; // rax
int v6; // er11
int v7; // er11
int v8; // er11
int v9; // er11
__int64 v10[2]; // [rsp+8h] [rbp-10h]

v1 = 0;
v10[0] = 0xFFFFFFFF00000001LL;
do
{
if ( (unsigned int)func4(v1, a1, 1) || (unsigned int)func5(v3, (_QWORD **)a1, v2) )
{
v4 = 1;
return *((unsigned int *)v10 + v4 - 1);
}
if ( (unsigned int)func4(v6, a1, -1) || (unsigned int)func5(v7, (_QWORD **)a1, -1) )
{
v4 = 2;
return *((unsigned int *)v10 + v4 - 1);
}
v1 = v8 + 1;
}
while ( v1 != 3 );
if ( (unsigned int)func6(a1, 1) || (unsigned int)func7(a1, 1) )
goto LABEL_11;
if ( (unsigned int)func6(a1, -1) || (result = func7(a1, -1), (_DWORD)result) )
{
v9 = 1;
LABEL_11:
result = HIDWORD(v10[v9 - 1]);
}
return result;
}

original_code:
int ttt_won_board(Board* board) {
 int i = 0, j = 0, strike = 0;
 int players[2] = { 1, -1 };
 while (!strike && (i < 3)) {
  while (!strike && (j < 2)) {
   strike = check_horizontal(i, board, players[j]);
   if (!strike) {
    strike = check_vertical(i, board, players[j]);
   }
   j++;
  }
  if (strike) {
   return players[j - 1];
  }
  j = 0;
  i++;
 }
 while (!strike && (j < 2)) {
  strike = check_main_diag(board, players[j]);
  if (!strike) {
   strike = check_sec_diag(board, players[j]);
  }
  j++;
 }
 if (strike) {
  return players[j - 1];
 }
 return 0;
}

canonical_original_code:
int ttt_won_board(struct board_s *board) {
 int i = 0; int j = 0; int strike = 0;
 int players[2] = { 1, -1 };
 while (!strike && (i < 3)) {
  while (!strike && (j < 2)) {
   strike = check_horizontal(i, board, players[j]);
   if (!strike) {
    strike = check_vertical(i, board, players[j]);
   }
   j++;
  }
  if (strike) {
   return players[j - 1];
  }
  j = 0;
  i++;
 }
 while (!strike && (j < 2)) {
  strike = check_main_diag(board, players[j]);
  if (!strike) {
   strike = check_sec_diag(board, players[j]);
  }
  j++;
 }
 if (strike) {
  return players[j - 1];
 }
 return 0;
}

variable_types:
players
int [2]


decompiled_code:
__int64 __fastcall ttt_won_game(_QWORD *a1)
{
__int64 result; // rax

if ( (unsigned int)board_full(*a1) && (result = ttt_won_board((_QWORD *)*a1), !(_DWORD)result) )
{
a1[2] = 0x100000000LL;
}
else
{
result = ttt_won_board((_QWORD *)*a1);
if ( (_DWORD)result )
{
*((_DWORD *)a1 + 5) = 1;
result = 1LL;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func9(_QWORD *a1)
{
__int64 result; // rax

if ( (unsigned int)board_full(*a1) && (result = func8((_QWORD *)*a1), !(_DWORD)result) )
{
a1[2] = 0x100000000LL;
}
else
{
result = func8((_QWORD *)*a1);
if ( (_DWORD)result )
{
*((_DWORD *)a1 + 5) = 1;
result = 1LL;
}
}
return result;
}

original_code:
int ttt_won_game(Game* game) {
 if (board_full(game->board) && !ttt_won_board(game->board)) {
  game->game_over = 1;
  game->current_player = 0;
  return 0;
 }
 if (ttt_won_board(game->board)) {
  game->game_over = 1;
  return 1;
 }
 return 0;
}

canonical_original_code:
int ttt_won_game(struct game_s *game) {
 if (board_full(game->board) && !ttt_won_board(game->board)) {
  game->game_over = 1;
  game->current_player = 0;
  return 0;
 }
 if (ttt_won_board(game->board)) {
  game->game_over = 1;
  return 1;
 }
 return 0;
}


decompiled_code:
__int64 __fastcall ttt_get_score(_QWORD *a1)
{
int v1; // eax
bool v2; // zf
__int64 result; // rax

v1 = ttt_won_board(a1);
if ( v1 == 1 )
return 100000LL;
v2 = v1 == -1;
result = 0LL;
if ( v2 )
result = 4294867296LL;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func10(_QWORD *a1)
{
int v1; // eax
bool v2; // zf
__int64 result; // rax

v1 = func8(a1);
if ( v1 == 1 )
return 100000LL;
v2 = v1 == -1;
result = 0LL;
if ( v2 )
result = 4294867296LL;
return result;
}

original_code:
int ttt_get_score(Board* board) {
 int who_won = ttt_won_board(board);
 if (who_won == 1) {
  return 100000;
 }
 if (who_won == -1) {
  return -100000;
 }
 return 0;
}

canonical_original_code:
int ttt_get_score(struct board_s *board) {
 int who_won = ttt_won_board(board);
 if (who_won == 1) {
  return 100000;
 }
 if (who_won == -1) {
  return -100000;
 }
 return 0;
}


decompiled_code:
__int64 __fastcall add_node_to_end(void ***a1, __int64 a2, __int64 a3, int a4)
{
void **v5; // rax
void **v6; // rbp
_QWORD *v7; // rax
_QWORD *v8; // rbx
_QWORD *v9; // rax
bool v10; // zf
void **v11; // rax
__int64 result; // rax

v5 = (void **)calloc(1uLL, 0x18uLL);
if ( v5 )
{
v6 = v5;
v7 = calloc(1uLL, 0x20uLL);
*v6 = v7;
v8 = v7;
if ( v7 )
{
v9 = malloc(8uLL);
v8[1] = v9;
if ( v9 )
{
v10 = *a1 == 0LL;
*v9 = a2;
*((_DWORD *)v8 + 4) = a4;
v6[1] = 0LL;
if ( v10 )
{
v6[2] = 0LL;
result = 1LL;
*a1 = v6;
a1[1] = v6;
}
else
{
v11 = a1[1];
v11[1] = v6;
a1[1] = v6;
v6[2] = v11;
result = 1LL;
}
}
else
{
puts("ERROR: standard function malloc has failed");
free(*v6);
free(v6);
result = 0LL;
}
}
else
{
puts("ERROR: standard function calloc has failed");
free(v6);
result = 0LL;
}
}
else
{
puts("ERROR: standard function calloc has failed");
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(void ***a1, __int64 a2, __int64 a3, int a4)
{
void **v5; // rax
void **v6; // rbp
_QWORD *v7; // rax
_QWORD *v8; // rbx
_QWORD *v9; // rax
bool v10; // zf
void **v11; // rax
__int64 result; // rax

v5 = (void **)calloc(1uLL, 0x18uLL);
if ( v5 )
{
v6 = v5;
v7 = calloc(1uLL, 0x20uLL);
*v6 = v7;
v8 = v7;
if ( v7 )
{
v9 = malloc(8uLL);
v8[1] = v9;
if ( v9 )
{
v10 = *a1 == 0LL;
*v9 = a2;
*((_DWORD *)v8 + 4) = a4;
v6[1] = 0LL;
if ( v10 )
{
v6[2] = 0LL;
result = 1LL;
*a1 = v6;
a1[1] = v6;
}
else
{
v11 = a1[1];
v11[1] = v6;
a1[1] = v6;
v6[2] = v11;
result = 1LL;
}
}
else
{
puts("ERROR: standard function malloc has failed");
free(*v6);
free(v6);
result = 0LL;
}
}
else
{
puts("ERROR: standard function calloc has failed");
free(v6);
result = 0LL;
}
}
else
{
puts("ERROR: standard function calloc has failed");
result = 0LL;
}
return result;
}

original_code:
int add_node_to_end(linked_list *nodes_list, Move move, Board *board, int value) {
    element *new_element;
    if ((new_element = (element*)calloc(1, sizeof(element))) == ((void *)0)) {
        printf("ERROR: standard function calloc has failed\n");
        return 0;
    }
    if ((new_element->node = (vertex*)calloc(1, sizeof(vertex))) == ((void *)0)) {
        printf("ERROR: standard function calloc has failed\n");
        free(new_element);
        return 0;
    }
    if ((new_element->node->current_move = (Move*)malloc(sizeof(Move))) == ((void *)0)) {
        printf("ERROR: standard function malloc has failed\n");
        free(new_element->node);
        free(new_element);
        return 0;
    }
    new_element->node->current_move->i = move.i;
    new_element->node->current_move->j = move.j;
    new_element->node->value = value;
    new_element->next = ((void *)0);
    if (nodes_list->head == ((void *)0)) {
        nodes_list->head = new_element;
        nodes_list->tail = new_element;
        new_element->prev = ((void *)0);
        return 1;
    }
    nodes_list->tail->next = new_element;
    new_element->prev = nodes_list->tail;
    nodes_list->tail = new_element;
    return 1;
}

canonical_original_code:
int add_node_to_end(struct linked_list_s *nodes_list, struct move_s move, struct board_s *board, int value) {
    struct element_s *new_element;
    if ((new_element = (struct element_s *)calloc(1, sizeof(element))) == ((void *)0)) {
        printf("ERROR: standard function calloc has failed\n");
        return 0;
    }
    if ((new_element->node = (struct vertex_s *)calloc(1, sizeof(vertex))) == ((void *)0)) {
        printf("ERROR: standard function calloc has failed\n");
        free(new_element);
        return 0;
    }
    if ((new_element->node->current_move = (struct move_s *)malloc(sizeof(Move))) == ((void *)0)) {
        printf("ERROR: standard function malloc has failed\n");
        free(new_element->node);
        free(new_element);
        return 0;
    }
    new_element->node->current_move->i = move.i;
    new_element->node->current_move->j = move.j;
    new_element->node->value = value;
    new_element->next = ((void *)0);
    if (nodes_list->head == ((void *)0)) {
        nodes_list->head = new_element;
        nodes_list->tail = new_element;
        new_element->prev = ((void *)0);
        return 1;
    }
    nodes_list->tail->next = new_element;
    new_element->prev = nodes_list->tail;
    nodes_list->tail = new_element;
    return 1;
}

variable_types: struct linked_list_s { struct element_s { struct vertex_s { int score; struct move_s { int i; int j; } *current_move; int value; struct linked_list_s *children; } *node; struct element_s *next; struct element_s *prev; } *head; struct element_s *tail; } *

variable_types:
move
struct move_s

variable_types: struct element_s { struct vertex_s { int score; struct move_s { int i; int j; } *current_move; int value; struct linked_list_s { struct element_s *head; struct element_s *tail; } *children; } *node; struct element_s *next; struct element_s *prev; } *