#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 */

/* Variables and functions */
int /*<<< orphan*/ fill2DArray(int **, int const, int const, int);
int /*<<< orphan*/ free2DArray(int **, int const);
int **make2DArray(int const, int const);
int /*<<< orphan*/ pong(int **);
int /*<<< orphan*/ printf(char *);
int /*<<< orphan*/ scanf(char *, int *);
int /*<<< orphan*/ snakeSinglePlayer(int **);
int /*<<< orphan*/ snakeTwoPlayer(int **);
int /*<<< orphan*/ tetrisSinglePlayer(int **);
int /*<<< orphan*/ tetrisTwoPlayer(int **);
int main(void) {
  const int arrayHeight = 38;
  const int arrayWidth = 76;
  bool **ledArray;
  ledArray = make2DArray(arrayHeight, arrayWidth);
  fill2DArray(ledArray, arrayHeight, arrayWidth, false);
  int input = 0;
  do {
    printf("Welcome to the game-o-matic!\nEnter \"1\" to play single player "
           "Snake!\nEnter \"2\" to play two player Snake!\nEnter \"3\" to play "
           "single player Tetris!\nEnter \"4\" to play two player "
           "Tetris!\nEnter \"5\" to play Pong!\nEnter \"0\" to exit.");
    scanf("%d", &input);
  } while (input < 0 || input > 5);
  if (input == 1) {
    snakeSinglePlayer(ledArray);
  }
  if (input == 2) {
    snakeTwoPlayer(ledArray);
  }
  if (input == 3) {
    tetrisSinglePlayer(ledArray);
  }
  if (input == 4) {
    tetrisTwoPlayer(ledArray);
  }
  if (input == 5) {
    pong(ledArray);
  }
  free2DArray(ledArray, arrayWidth);
  return 0;
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
movl   $0x0,-0x4(%rbp)
movl   $0x26,-0x8(%rbp)
movl   $0x4c,-0xc(%rbp)
mov    $0x26,%edi
mov    $0x4c,%esi
call   10b0 <make2DArray@plt>
mov    %rax,-0x18(%rbp)
mov    -0x18(%rbp),%rdi
mov    $0x26,%esi
mov    $0x4c,%edx
xor    %ecx,%ecx
call   1090 <fill2DArray@plt>
movl   $0x0,-0x1c(%rbp)
lea    0xe0d(%rip),%rdi
call   1050 <printf@plt>
lea    0xee1(%rip),%rdi
lea    -0x1c(%rbp),%rsi
call   10a0 <scanf@plt>
mov    $0x1,%al
cmpl   $0x0,-0x1c(%rbp)
mov    %al,-0x1d(%rbp)
jl     1221 <main+0x81>
cmpl   $0x5,-0x1c(%rbp)
setg   %al
mov    %al,-0x1d(%rbp)
mov    -0x1d(%rbp),%al
test   $0x1,%al
jne    11ec <main+0x4c>
cmpl   $0x1,-0x1c(%rbp)
jne    123f <main+0x9f>
mov    -0x18(%rbp),%rdi
call   1070 <snakeSinglePlayer@plt>
cmpl   $0x2,-0x1c(%rbp)
jne    1252 <main+0xb2>
mov    -0x18(%rbp),%rdi
call   1060 <snakeTwoPlayer@plt>
cmpl   $0x3,-0x1c(%rbp)
jne    1265 <main+0xc5>
mov    -0x18(%rbp),%rdi
call   10c0 <tetrisSinglePlayer@plt>
cmpl   $0x4,-0x1c(%rbp)
jne    1278 <main+0xd8>
mov    -0x18(%rbp),%rdi
call   1080 <tetrisTwoPlayer@plt>
cmpl   $0x5,-0x1c(%rbp)
jne    128b <main+0xeb>
mov    -0x18(%rbp),%rdi
call   1030 <pong@plt>
mov    -0x18(%rbp),%rdi
mov    $0x4c,%esi
call   1040 <free2DArray@plt>
xor    %eax,%eax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %r15
push   %r14
push   %r12
push   %rbx
push   %rax
mov    $0x26,%edi
mov    $0x4c,%esi
call   10b0 <make2DArray@plt>
mov    %rax,%r14
mov    %rax,%rdi
mov    $0x26,%esi
mov    $0x4c,%edx
xor    %ecx,%ecx
call   1090 <fill2DArray@plt>
movl   $0x0,0x4(%rsp)
lea    0xe23(%rip),%r15
lea    0xefc(%rip),%r12
lea    0x4(%rsp),%rbx
nopl   0x0(%rax)
mov    %r15,%rdi
call   1050 <printf@plt>
mov    %r12,%rdi
mov    %rbx,%rsi
call   10a0 <scanf@plt>
mov    0x4(%rsp),%eax
cmp    $0x5,%eax
ja     11f0 <main+0x50>
cmp    $0x1,%eax
je     1248 <main+0xa8>
cmp    $0x2,%eax
je     1259 <main+0xb9>
cmp    $0x3,%eax
je     126a <main+0xca>
cmp    $0x4,%eax
je     127b <main+0xdb>
cmp    $0x5,%eax
jne    122d <main+0x8d>
mov    %r14,%rdi
call   1030 <pong@plt>
mov    %r14,%rdi
mov    $0x4c,%esi
call   1040 <free2DArray@plt>
xor    %eax,%eax
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
ret
mov    %r14,%rdi
call   1070 <snakeSinglePlayer@plt>
mov    0x4(%rsp),%eax
cmp    $0x2,%eax
jne    1216 <main+0x76>
mov    %r14,%rdi
call   1060 <snakeTwoPlayer@plt>
mov    0x4(%rsp),%eax
cmp    $0x3,%eax
jne    121b <main+0x7b>
mov    %r14,%rdi
call   10c0 <tetrisSinglePlayer@plt>
mov    0x4(%rsp),%eax
cmp    $0x4,%eax
jne    1220 <main+0x80>
mov    %r14,%rdi
call   1080 <tetrisTwoPlayer@plt>
mov    0x4(%rsp),%eax
cmp    $0x5,%eax
je     1225 <main+0x85>
jmp    122d <main+0x8d>

LLVM IR (-O0):
@.str = [224 x i8] c"Welcome to the game-o-matic!\0AEnter \221\22 to play single player Snake!\0AEnter \222\22 to play two player Snake!\0AEnter \223\22 to play single player Tetris!\0AEnter \224\22 to play two player Tetris!\0AEnter \225\22 to play Pong!\0AEnter \220\22 to exit.\00"
@.str.1 = [3 x i8] c"%d\00"
define i32 @main() {
%1 = alloca i32
%2 = alloca i32
%3 = alloca i32
%4 = alloca i32**
%5 = alloca i32
store i32 0, i32* %1
store i32 38, i32* %2
store i32 76, i32* %3
%6 = call i32** @make2DArray(i32 38, i32 76)
store i32** %6, i32*** %4
%7 = load i32**, i32*** %4
%8 = call i32 @fill2DArray(i32** %7, i32 38, i32 76, i32 0)
store i32 0, i32* %5
br label %9
9: ; preds = %18, %0
%10 = call i32 @printf(i8* getelementptr inbounds ([224 x i8], [224 x i8]* @.str, i64 0, i64 0))
%11 = call i32 @scanf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i64 0, i64 0), i32* %5)
br label %12
12: ; preds = %9
%13 = load i32, i32* %5
%14 = icmp slt i32 %13, 0
br i1 %14, label %18, label %15
15: ; preds = %12
%16 = load i32, i32* %5
%17 = icmp sgt i32 %16, 5
br label %18
18: ; preds = %15, %12
%19 = phi i1 [ true, %12 ], [ %17, %15 ]
br i1 %19, label %9, label %20
20: ; preds = %18
%21 = load i32, i32* %5
%22 = icmp eq i32 %21, 1
br i1 %22, label %23, label %26
23: ; preds = %20
%24 = load i32**, i32*** %4
%25 = call i32 @snakeSinglePlayer(i32** %24)
br label %26
26: ; preds = %23, %20
%27 = load i32, i32* %5
%28 = icmp eq i32 %27, 2
br i1 %28, label %29, label %32
29: ; preds = %26
%30 = load i32**, i32*** %4
%31 = call i32 @snakeTwoPlayer(i32** %30)
br label %32
32: ; preds = %29, %26
%33 = load i32, i32* %5
%34 = icmp eq i32 %33, 3
br i1 %34, label %35, label %38
35: ; preds = %32
%36 = load i32**, i32*** %4
%37 = call i32 @tetrisSinglePlayer(i32** %36)
br label %38
38: ; preds = %35, %32
%39 = load i32, i32* %5
%40 = icmp eq i32 %39, 4
br i1 %40, label %41, label %44
41: ; preds = %38
%42 = load i32**, i32*** %4
%43 = call i32 @tetrisTwoPlayer(i32** %42)
br label %44
44: ; preds = %41, %38
%45 = load i32, i32* %5
%46 = icmp eq i32 %45, 5
br i1 %46, label %47, label %50
47: ; preds = %44
%48 = load i32**, i32*** %4
%49 = call i32 @pong(i32** %48)
br label %50
50: ; preds = %47, %44
%51 = load i32**, i32*** %4
%52 = call i32 @free2DArray(i32** %51, i32 76)
ret i32 0
}

LLVM IR (-O2):
@.str = [224 x i8] c"Welcome to the game-o-matic!\0AEnter \221\22 to play single player Snake!\0AEnter \222\22 to play two player Snake!\0AEnter \223\22 to play single player Tetris!\0AEnter \224\22 to play two player Tetris!\0AEnter \225\22 to play Pong!\0AEnter \220\22 to exit.\00"
@.str.1 = [3 x i8] c"%d\00"
define i32 @main() {
%1 = alloca i32
%2 = tail call i32** @make2DArray(i32 38, i32 76)
%3 = tail call i32 @fill2DArray(i32** %2, i32 38, i32 76, i32 0)
%4 = bitcast i32* %1 to i8*
store i32 0, i32* %1
br label %5
5: ; preds = %5, %0
%6 = call i32 @printf(i8* dereferenceable(1) getelementptr inbounds ([224 x i8], [224 x i8]* @.str, i64 0, i64 0))
%7 = call i32 @scanf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i64 0, i64 0), i32* %1)
%8 = load i32, i32* %1
%9 = icmp ugt i32 %8, 5
br i1 %9, label %5, label %10
10: ; preds = %5
%11 = icmp eq i32 %8, 1
br i1 %11, label %12, label %15
12: ; preds = %10
%13 = call i32 @snakeSinglePlayer(i32** %2)
%14 = load i32, i32* %1
br label %15
15: ; preds = %12, %10
%16 = phi i32 [ %14, %12 ], [ %8, %10 ]
%17 = icmp eq i32 %16, 2
br i1 %17, label %18, label %21
18: ; preds = %15
%19 = call i32 @snakeTwoPlayer(i32** %2)
%20 = load i32, i32* %1
br label %21
21: ; preds = %18, %15
%22 = phi i32 [ %20, %18 ], [ %16, %15 ]
%23 = icmp eq i32 %22, 3
br i1 %23, label %24, label %27
24: ; preds = %21
%25 = call i32 @tetrisSinglePlayer(i32** %2)
%26 = load i32, i32* %1
br label %27
27: ; preds = %24, %21
%28 = phi i32 [ %26, %24 ], [ %22, %21 ]
%29 = icmp eq i32 %28, 4
br i1 %29, label %30, label %33
30: ; preds = %27
%31 = call i32 @tetrisTwoPlayer(i32** %2)
%32 = load i32, i32* %1
br label %33
33: ; preds = %30, %27
%34 = phi i32 [ %32, %30 ], [ %28, %27 ]
%35 = icmp eq i32 %34, 5
br i1 %35, label %36, label %38
36: ; preds = %33
%37 = call i32 @pong(i32** %2)
br label %38
38: ; preds = %36, %33
%39 = call i32 @free2DArray(i32** %2, i32 76)
ret i32 0
}