#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
typedef size_t uint32_t;

/* Variables and functions */
char checkWin(char **);
int /*<<< orphan*/ clearBoardArea();
int /*<<< orphan*/ drawBoard();
int /*<<< orphan*/ drawMark(int, size_t, unsigned char);
char formatString(char *, char *, int /*<<< orphan*/, ...);
int /*<<< orphan*/ print(char *, char);
char readLine(char *, int);
int /*<<< orphan*/ setForeColor(int);
size_t stringToInt(char *);
int /*<<< orphan*/ terminalClear();
int /*<<< orphan*/ timerWaitMs(int);
void connectFour() {
  char inputBuffer[4];
  char welcomeMessage[] = "Welcome to Connect Four v9.3\n";
  char choicePrompt[] = "Player %d please choose column 0-5:";
  char winMessage1[] = "Player 1 (Mika) has won!";
  char winMessage2[] = "Player 2 (Takahashi) has won!";
  char messageBuffer[40];
  unsigned char player = 1;
  char length;
  char board[6][6] = {{0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0},
                      {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0},
                      {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}};
  uint32_t column;
  char count;
  char playerHasWon = 0;
  terminalClear();
  setForeColor(0xFABF);
  drawBoard();
  print(welcomeMessage, 29);
  while (playerHasWon == 0) {
    length = formatString(choicePrompt, messageBuffer, 0, 0, player);
    print(messageBuffer, length);
    length = readLine(inputBuffer, 4);
    column = stringToInt(inputBuffer);
    count = 0;
    while ((board[count][column]) != 0) {
      count++;
    }
    board[count][column] = player;
    setForeColor(0xFABF);
    drawMark((5 - count), column, player);
    playerHasWon = checkWin(board);
    if (playerHasWon == 1) {
      terminalClear();
      length = formatString(winMessage1, messageBuffer, 0);
      print(winMessage1, length);
    } else if (playerHasWon == 2) {
      terminalClear();
      length = formatString(winMessage2, messageBuffer, 0);
      print(winMessage2, length);
    }
    if (player == 1) {
      player = 2;
    } else {
      player = 1;
    }
  }
  timerWaitMs(2500000);
  clearBoardArea();
}


x86 assembly (clang, -O0):
<connectFour>:
push   %rbp
mov    %rsp,%rbp
sub    $0x110,%rsp
mov    0xe1e(%rip),%rax
mov    %rax,-0x30(%rbp)
mov    0xe1b(%rip),%rax
mov    %rax,-0x28(%rbp)
mov    0xe18(%rip),%rax
mov    %rax,-0x20(%rbp)
mov    0xe16(%rip),%eax
mov    %eax,-0x18(%rbp)
mov    0xe10(%rip),%ax
mov    %ax,-0x14(%rbp)
lea    -0x60(%rbp),%rdi
lea    0xe05(%rip),%rsi
mov    $0x24,%edx
call   10b0 <memcpy@plt>
mov    0xe24(%rip),%rax
mov    %rax,-0x80(%rbp)
mov    0xe21(%rip),%rax
mov    %rax,-0x78(%rbp)
mov    0xe1e(%rip),%rax
mov    %rax,-0x70(%rbp)
mov    0xe1c(%rip),%al
mov    %al,-0x68(%rbp)
mov    0xe1a(%rip),%rax
mov    %rax,-0xa0(%rbp)
mov    0xe14(%rip),%rax
mov    %rax,-0x98(%rbp)
mov    0xe0e(%rip),%rax
mov    %rax,-0x90(%rbp)
mov    0xe09(%rip),%eax
mov    %eax,-0x88(%rbp)
mov    0xe00(%rip),%ax
mov    %ax,-0x84(%rbp)
movb   $0x1,-0xd1(%rbp)
lea    -0x100(%rbp),%rdi
xor    %esi,%esi
mov    $0x24,%edx
call   1070 <memset@plt>
movb   $0x0,-0x10a(%rbp)
mov    $0x0,%al
call   10e0 <terminalClear@plt>
mov    $0xfabf,%edi
call   10f0 <setForeColor@plt>
mov    $0x0,%al
call   10a0 <drawBoard@plt>
lea    -0x30(%rbp),%rdi
mov    $0x1d,%esi
call   1090 <print@plt>
movsbl -0x10a(%rbp),%eax
cmp    $0x0,%eax
jne    14a6 <connectFour+0x2d6>
lea    -0x60(%rbp),%rdi
lea    -0xd0(%rbp),%rsi
movzbl -0xd1(%rbp),%r8d
ff
xor    %ecx,%ecx
mov    %ecx,%edx
mov    $0x0,%al
call   1040 <formatString@plt>
mov    %al,-0xd2(%rbp)
lea    -0xd0(%rbp),%rdi
movsbl -0xd2(%rbp),%esi
call   1090 <print@plt>
lea    -0x4(%rbp),%rdi
mov    $0x4,%esi
call   10c0 <readLine@plt>
mov    %al,-0xd2(%rbp)
lea    -0x4(%rbp),%rdi
call   10d0 <stringToInt@plt>
mov    %rax,-0x108(%rbp)
movb   $0x0,-0x109(%rbp)
movsbq -0x109(%rbp),%rcx
ff
lea    -0x100(%rbp),%rax
imul   $0x6,%rcx,%rcx
add    %rcx,%rax
mov    -0x108(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x0,%eax
je     1389 <connectFour+0x1b9>
mov    -0x109(%rbp),%al
add    $0x1,%al
mov    %al,-0x109(%rbp)
jmp    134c <connectFour+0x17c>
mov    -0xd1(%rbp),%dl
movsbq -0x109(%rbp),%rcx
ff
lea    -0x100(%rbp),%rax
imul   $0x6,%rcx,%rcx
add    %rcx,%rax
mov    -0x108(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    $0xfabf,%edi
call   10f0 <setForeColor@plt>
movsbl -0x109(%rbp),%eax
mov    $0x5,%edi
sub    %eax,%edi
mov    -0x108(%rbp),%rsi
movzbl -0xd1(%rbp),%edx
call   1030 <drawMark@plt>
lea    -0x100(%rbp),%rdi
call   1060 <checkWin@plt>
mov    %al,-0x10a(%rbp)
movsbl -0x10a(%rbp),%eax
cmp    $0x1,%eax
jne    1432 <connectFour+0x262>
mov    $0x0,%al
call   10e0 <terminalClear@plt>
lea    -0x80(%rbp),%rdi
lea    -0xd0(%rbp),%rsi
xor    %edx,%edx
mov    $0x0,%al
call   1040 <formatString@plt>
mov    %al,-0xd2(%rbp)
lea    -0x80(%rbp),%rdi
movsbl -0xd2(%rbp),%esi
call   1090 <print@plt>
jmp    147e <connectFour+0x2ae>
movsbl -0x10a(%rbp),%eax
cmp    $0x2,%eax
jne    1479 <connectFour+0x2a9>
mov    $0x0,%al
call   10e0 <terminalClear@plt>
lea    -0xa0(%rbp),%rdi
lea    -0xd0(%rbp),%rsi
xor    %edx,%edx
mov    $0x0,%al
call   1040 <formatString@plt>
mov    %al,-0xd2(%rbp)
lea    -0xa0(%rbp),%rdi
movsbl -0xd2(%rbp),%esi
call   1090 <print@plt>
jmp    147e <connectFour+0x2ae>
movzbl -0xd1(%rbp),%eax
cmp    $0x1,%eax
jne    149a <connectFour+0x2ca>
movb   $0x2,-0xd1(%rbp)
jmp    14a1 <connectFour+0x2d1>
movb   $0x1,-0xd1(%rbp)
jmp    12da <connectFour+0x10a>
mov    $0x2625a0,%edi
call   1080 <timerWaitMs@plt>
mov    $0x0,%al
call   1050 <clearBoardArea@plt>
add    $0x110,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<connectFour>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0xf8,%rsp
movups 0xe46(%rip),%xmm0
movups %xmm0,0xbe(%rsp)
movaps 0xe29(%rip),%xmm0
movaps %xmm0,0xb0(%rsp)
movaps 0xe4a(%rip),%xmm0
movaps %xmm0,0x70(%rsp)
movaps 0xe2e(%rip),%xmm0
movaps %xmm0,0x60(%rsp)
movl   $0x3a352d,0x80(%rsp)
movups 0xe50(%rip),%xmm0
movups %xmm0,0x49(%rsp)
movaps 0xe3b(%rip),%xmm0
movaps %xmm0,0x40(%rsp)
movups 0xe5d(%rip),%xmm0
movups %xmm0,0x9e(%rsp)
movaps 0xe40(%rip),%xmm0
movaps %xmm0,0x90(%rsp)
xorps  %xmm0,%xmm0
movaps %xmm0,0x20(%rsp)
movaps %xmm0,0x10(%rsp)
movl   $0x0,0x30(%rsp)
xor    %eax,%eax
call   10c0 <terminalClear@plt>
mov    $0xfabf,%edi
call   10d0 <setForeColor@plt>
xor    %eax,%eax
call   1090 <drawBoard@plt>
lea    0xb0(%rsp),%rdi
mov    $0x1d,%esi
call   1080 <print@plt>
mov    $0x1,%r14b
lea    0xd0(%rsp),%r15
lea    0xc(%rsp),%r13
nopw   0x0(%rax,%rax,1)
movzbl %r14b,%ebp
lea    0x60(%rsp),%rdi
mov    %r15,%rsi
xor    %edx,%edx
xor    %ecx,%ecx
mov    %ebp,%r8d
xor    %eax,%eax
call   1040 <formatString@plt>
movsbl %al,%esi
mov    %r15,%rdi
call   1080 <print@plt>
mov    %r13,%rdi
mov    $0x4,%esi
call   10a0 <readLine@plt>
mov    %r13,%rdi
call   10b0 <stringToInt@plt>
mov    %rax,%rbx
mov    $0xff,%r12b
add    $0x1,%r12b
movsbq %r12b,%rax
lea    (%rax,%rax,2),%rax
lea    (%rsp,%rax,2),%rax
add    $0x10,%rax
cmpb   $0x0,(%rbx,%rax,1)
jne    12d0 <connectFour+0x120>
add    %rbx,%rax
mov    %bpl,(%rax)
mov    $0xfabf,%edi
call   10d0 <setForeColor@plt>
movsbl %r12b,%eax
mov    $0x5,%edi
sub    %eax,%edi
mov    %rbx,%rsi
mov    %ebp,%edx
call   1030 <drawMark@plt>
lea    0x10(%rsp),%rdi
call   1060 <checkWin@plt>
cmp    $0x1,%al
je     1337 <connectFour+0x187>
cmp    $0x2,%al
je     133e <connectFour+0x18e>
cmp    $0x1,%r14b
sete   %r14b
add    $0x1,%r14b
test   %al,%al
je     1290 <connectFour+0xe0>
jmp    136c <connectFour+0x1bc>
lea    0x40(%rsp),%rbx
jmp    1346 <connectFour+0x196>
lea    0x90(%rsp),%rbx
xor    %eax,%eax
call   10c0 <terminalClear@plt>
lea    0xd0(%rsp),%rsi
mov    %rbx,%rdi
xor    %edx,%edx
xor    %eax,%eax
call   1040 <formatString@plt>
movsbl %al,%esi
mov    %rbx,%rdi
call   1080 <print@plt>
mov    $0x2625a0,%edi
call   1070 <timerWaitMs@plt>
xor    %eax,%eax
call   1050 <clearBoardArea@plt>
add    $0xf8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@__const.connectFour.welcomeMessage = [30 x i8] c"Welcome to Connect Four v9.3\0A\00"
@__const.connectFour.choicePrompt = [36 x i8] c"Player %d please choose column 0-5:\00"
@__const.connectFour.winMessage1 = [25 x i8] c"Player 1 (Mika) has won!\00"
@__const.connectFour.winMessage2 = [30 x i8] c"Player 2 (Takahashi) has won!\00"
define void @connectFour() {
%1 = alloca [4 x i8]
%2 = alloca [30 x i8]
%3 = alloca [36 x i8]
%4 = alloca [25 x i8]
%5 = alloca [30 x i8]
%6 = alloca [40 x i8]
%7 = alloca i8
%8 = alloca i8
%9 = alloca [6 x [6 x i8]]
%10 = alloca i64
%11 = alloca i8
%12 = alloca i8
%13 = bitcast [30 x i8]* %2 to i8*
%14 = bitcast [36 x i8]* %3 to i8*
%15 = bitcast [25 x i8]* %4 to i8*
%16 = bitcast [30 x i8]* %5 to i8*
store i8 1, i8* %7
%17 = bitcast [6 x [6 x i8]]* %9 to i8*
store i8 0, i8* %12
%18 = call i32 (...) @terminalClear()
%19 = call i32 @setForeColor(i32 64191)
%20 = call i32 (...) @drawBoard()
%21 = getelementptr inbounds [30 x i8], [30 x i8]* %2, i64 0, i64 0
%22 = call i32 @print(i8* %21, i8 signext 29)
br label %23
23: ; preds = %99, %0
%24 = load i8, i8* %12
%25 = sext i8 %24 to i32
%26 = icmp eq i32 %25, 0
br i1 %26, label %27, label %100
27: ; preds = %23
%28 = getelementptr inbounds [36 x i8], [36 x i8]* %3, i64 0, i64 0
%29 = getelementptr inbounds [40 x i8], [40 x i8]* %6, i64 0, i64 0
%30 = load i8, i8* %7
%31 = zext i8 %30 to i32
%32 = call signext i8 (i8*, i8*, i32, ...) @formatString(i8* %28, i8* %29, i32 0, i32 0, i32 %31)
store i8 %32, i8* %8
%33 = getelementptr inbounds [40 x i8], [40 x i8]* %6, i64 0, i64 0
%34 = load i8, i8* %8
%35 = call i32 @print(i8* %33, i8 signext %34)
%36 = getelementptr inbounds [4 x i8], [4 x i8]* %1, i64 0, i64 0
%37 = call signext i8 @readLine(i8* %36, i32 4)
store i8 %37, i8* %8
%38 = getelementptr inbounds [4 x i8], [4 x i8]* %1, i64 0, i64 0
%39 = call i64 @stringToInt(i8* %38)
store i64 %39, i64* %10
store i8 0, i8* %11
br label %40
40: ; preds = %49, %27
%41 = load i8, i8* %11
%42 = sext i8 %41 to i64
%43 = getelementptr inbounds [6 x [6 x i8]], [6 x [6 x i8]]* %9, i64 0, i64 %42
%44 = load i64, i64* %10
%45 = getelementptr inbounds [6 x i8], [6 x i8]* %43, i64 0, i64 %44
%46 = load i8, i8* %45
%47 = sext i8 %46 to i32
%48 = icmp ne i32 %47, 0
br i1 %48, label %49, label %52
49: ; preds = %40
%50 = load i8, i8* %11
%51 = add i8 %50, 1
store i8 %51, i8* %11
br label %40
52: ; preds = %40
%53 = load i8, i8* %7
%54 = load i8, i8* %11
%55 = sext i8 %54 to i64
%56 = getelementptr inbounds [6 x [6 x i8]], [6 x [6 x i8]]* %9, i64 0, i64 %55
%57 = load i64, i64* %10
%58 = getelementptr inbounds [6 x i8], [6 x i8]* %56, i64 0, i64 %57
store i8 %53, i8* %58
%59 = call i32 @setForeColor(i32 64191)
%60 = load i8, i8* %11
%61 = sext i8 %60 to i32
%62 = sub nsw i32 5, %61
%63 = load i64, i64* %10
%64 = load i8, i8* %7
%65 = call i32 @drawMark(i32 %62, i64 %63, i8 zeroext %64)
%66 = getelementptr inbounds [6 x [6 x i8]], [6 x [6 x i8]]* %9, i64 0, i64 0
%67 = bitcast [6 x i8]* %66 to i8**
%68 = call signext i8 @checkWin(i8** %67)
store i8 %68, i8* %12
%69 = load i8, i8* %12
%70 = sext i8 %69 to i32
%71 = icmp eq i32 %70, 1
br i1 %71, label %72, label %80
72: ; preds = %52
%73 = call i32 (...) @terminalClear()
%74 = getelementptr inbounds [25 x i8], [25 x i8]* %4, i64 0, i64 0
%75 = getelementptr inbounds [40 x i8], [40 x i8]* %6, i64 0, i64 0
%76 = call signext i8 (i8*, i8*, i32, ...) @formatString(i8* %74, i8* %75, i32 0)
store i8 %76, i8* %8
%77 = getelementptr inbounds [25 x i8], [25 x i8]* %4, i64 0, i64 0
%78 = load i8, i8* %8
%79 = call i32 @print(i8* %77, i8 signext %78)
br label %93
80: ; preds = %52
%81 = load i8, i8* %12
%82 = sext i8 %81 to i32
%83 = icmp eq i32 %82, 2
br i1 %83, label %84, label %92
84: ; preds = %80
%85 = call i32 (...) @terminalClear()
%86 = getelementptr inbounds [30 x i8], [30 x i8]* %5, i64 0, i64 0
%87 = getelementptr inbounds [40 x i8], [40 x i8]* %6, i64 0, i64 0
%88 = call signext i8 (i8*, i8*, i32, ...) @formatString(i8* %86, i8* %87, i32 0)
store i8 %88, i8* %8
%89 = getelementptr inbounds [30 x i8], [30 x i8]* %5, i64 0, i64 0
%90 = load i8, i8* %8
%91 = call i32 @print(i8* %89, i8 signext %90)
br label %92
92: ; preds = %84, %80
br label %93
93: ; preds = %92, %72
%94 = load i8, i8* %7
%95 = zext i8 %94 to i32
%96 = icmp eq i32 %95, 1
br i1 %96, label %97, label %98
97: ; preds = %93
store i8 2, i8* %7
br label %99
98: ; preds = %93
store i8 1, i8* %7
br label %99
99: ; preds = %98, %97
br label %23
100: ; preds = %23
%101 = call i32 @timerWaitMs(i32 2500000)
%102 = call i32 (...) @clearBoardArea()
ret void
}

LLVM IR (-O2):
@__const.connectFour.welcomeMessage = [30 x i8] c"Welcome to Connect Four v9.3\0A\00"
@__const.connectFour.choicePrompt = [36 x i8] c"Player %d please choose column 0-5:\00"
@__const.connectFour.winMessage1 = [25 x i8] c"Player 1 (Mika) has won!\00"
@__const.connectFour.winMessage2 = [30 x i8] c"Player 2 (Takahashi) has won!\00"
define void @connectFour() {
%1 = alloca [4 x i8]
%2 = alloca [30 x i8]
%3 = alloca [36 x i8]
%4 = alloca [25 x i8]
%5 = alloca [30 x i8]
%6 = alloca [40 x i8]
%7 = alloca [6 x [6 x i8]]
%8 = getelementptr inbounds [4 x i8], [4 x i8]* %1, i64 0, i64 0
%9 = getelementptr inbounds [30 x i8], [30 x i8]* %2, i64 0, i64 0
%10 = getelementptr inbounds [36 x i8], [36 x i8]* %3, i64 0, i64 0
%11 = getelementptr inbounds [25 x i8], [25 x i8]* %4, i64 0, i64 0
%12 = getelementptr inbounds [30 x i8], [30 x i8]* %5, i64 0, i64 0
%13 = getelementptr inbounds [40 x i8], [40 x i8]* %6, i64 0, i64 0
%14 = getelementptr inbounds [6 x [6 x i8]], [6 x [6 x i8]]* %7, i64 0, i64 0, i64 0
%15 = tail call i32 (...) @terminalClear()
%16 = tail call i32 @setForeColor(i32 64191)
%17 = tail call i32 (...) @drawBoard()
%18 = call i32 @print(i8* %9, i8 signext 29)
%19 = bitcast [6 x [6 x i8]]* %7 to i8**
br label %20
20: ; preds = %0, %40
%21 = phi i8 [ 1, %0 ], [ %42, %40 ]
%22 = zext i8 %21 to i32
%23 = call signext i8 (i8*, i8*, i32, ...) @formatString(i8* %10, i8* %13, i32 0, i32 0, i32 %22)
%24 = call i32 @print(i8* %13, i8 signext %23)
%25 = call signext i8 @readLine(i8* %8, i32 4)
%26 = call i64 @stringToInt(i8* %8)
br label %27
27: ; preds = %27, %20
%28 = phi i8 [ 0, %20 ], [ %33, %27 ]
%29 = sext i8 %28 to i64
%30 = getelementptr inbounds [6 x [6 x i8]], [6 x [6 x i8]]* %7, i64 0, i64 %29, i64 %26
%31 = load i8, i8* %30
%32 = icmp eq i8 %31, 0
%33 = add i8 %28, 1
br i1 %32, label %34, label %27
34: ; preds = %27
store i8 %21, i8* %30
%35 = call i32 @setForeColor(i32 64191)
%36 = sext i8 %28 to i32
%37 = sub nsw i32 5, %36
%38 = call i32 @drawMark(i32 %37, i64 %26, i8 zeroext %21)
%39 = call signext i8 @checkWin(i8** %19)
switch i8 %39, label %40 [
i8 1, label %45
i8 2, label %44
]
40: ; preds = %34
%41 = icmp eq i8 %21, 1
%42 = select i1 %41, i8 2, i8 1
%43 = icmp eq i8 %39, 0
br i1 %43, label %20, label %50
44: ; preds = %34
br label %45
45: ; preds = %34, %44
%46 = phi i8* [ %12, %44 ], [ %11, %34 ]
%47 = call i32 (...) @terminalClear()
%48 = call signext i8 (i8*, i8*, i32, ...) @formatString(i8* %46, i8* %13, i32 0)
%49 = call i32 @print(i8* %46, i8 signext %48)
br label %50
50: ; preds = %40, %45
%51 = call i32 @timerWaitMs(i32 2500000)
%52 = call i32 (...) @clearBoardArea()
ret void
}