#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 */
char EOF;
int EXIT_SUCCESS;
int /*<<< orphan*/ OnLose();
int /*<<< orphan*/ OnWin();
int RollDiceSum(int);
char getchar();
int /*<<< orphan*/ printf(char *, ...);
int scanf(char *, char *);
int /*<<< orphan*/ srand(unsigned int);
scalar_t__ time(int /*<<< orphan*/ *);
char tolower(char);
int main(void) {
  unsigned int seed = (unsigned int)time(NULL);
  srand(seed);
  int roll = 0;
  int sum = 0;
  int diceCount = 2;
  int wins = 0;
  int losses = 0;
  int isGameOver = 0;
  while (1) {
    isGameOver = 0;
    roll = 0;
    while (!isGameOver) {
      sum = RollDiceSum(diceCount);
      printf("You rolled %d.\n", sum);
      if (roll == 1) {
        if (sum == 7 || sum == 11) {
          OnWin();
          ++wins;
          isGameOver = 1;
        } else if (sum == 2 || sum == 3 || sum == 12) {
          OnLose();
          ++losses;
          isGameOver = 1;
        }
      } else if (sum == 7) {
        OnLose();
        ++losses;
        isGameOver = 1;
      }
      ++roll;
    }
    char answer = '\0';
    char c = '\0';
    printf("Would you like to play again? (y/n)\n");
    while (scanf(" %c", &answer) != 1) {
      printf("I am sorry, didn't quite get it.\n"
             "Would you like to play again? (y/n)\n");
      while ((c = getchar()) != '\n' && c != EOF)
        continue;
    }
    while ((c = getchar()) != '\n' && c != EOF)
      continue;
    if (tolower(answer) != 'y') {
      printf("%d wins, %d losses.\n", wins, losses);
      break;
    }
  }
  getchar();
  return EXIT_SUCCESS;
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
movl   $0x0,-0x4(%rbp)
xor    %eax,%eax
mov    %eax,%edi
call   1090 <time@plt>
mov    %eax,-0x8(%rbp)
mov    -0x8(%rbp),%edi
call   1070 <srand@plt>
movl   $0x0,-0xc(%rbp)
movl   $0x0,-0x10(%rbp)
movl   $0x2,-0x14(%rbp)
movl   $0x0,-0x18(%rbp)
movl   $0x0,-0x1c(%rbp)
movl   $0x0,-0x20(%rbp)
movl   $0x0,-0x20(%rbp)
movl   $0x0,-0xc(%rbp)
cmpl   $0x0,-0x20(%rbp)
setne  %al
xor    $0xff,%al
test   $0x1,%al
jne    1201 <main+0x71>
jmp    12ca <main+0x13a>
mov    -0x14(%rbp),%edi
call   1040 <RollDiceSum@plt>
mov    %eax,-0x10(%rbp)
mov    -0x10(%rbp),%esi
lea    0xdea(%rip),%rdi
mov    $0x0,%al
call   1050 <printf@plt>
cmpl   $0x1,-0xc(%rbp)
jne    1296 <main+0x106>
cmpl   $0x7,-0x10(%rbp)
je     123b <main+0xab>
cmpl   $0xb,-0x10(%rbp)
jne    1257 <main+0xc7>
mov    $0x0,%al
call   1030 <OnWin@plt>
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
movl   $0x1,-0x20(%rbp)
jmp    1291 <main+0x101>
cmpl   $0x2,-0x10(%rbp)
je     1275 <main+0xe5>
cmpl   $0x3,-0x10(%rbp)
je     1275 <main+0xe5>
cmpl   $0xc,-0x10(%rbp)
jne    128c <main+0xfc>
mov    $0x0,%al
call   1060 <OnLose@plt>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
movl   $0x1,-0x20(%rbp)
jmp    1291 <main+0x101>
jmp    12bc <main+0x12c>
cmpl   $0x7,-0x10(%rbp)
jne    12b7 <main+0x127>
mov    $0x0,%al
call   1060 <OnLose@plt>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
movl   $0x1,-0x20(%rbp)
jmp    12bc <main+0x12c>
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xc(%rbp)
jmp    11eb <main+0x5b>
movb   $0x0,-0x21(%rbp)
movb   $0x0,-0x22(%rbp)
lea    0xd5c(%rip),%rdi
mov    $0x0,%al
call   1050 <printf@plt>
lea    0xd29(%rip),%rdi
lea    -0x21(%rbp),%rsi
call   10b0 <scanf@plt>
cmp    $0x1,%eax
je     1352 <main+0x1c2>
lea    0xd14(%rip),%rdi
mov    $0x0,%al
call   1050 <printf@plt>
mov    $0x0,%al
call   1080 <getchar@plt>
mov    %al,-0x22(%rbp)
movsbl %al,%ecx
xor    %eax,%eax
cmp    $0xa,%ecx
mov    %al,-0x23(%rbp)
je     1338 <main+0x1a8>
movsbl -0x22(%rbp),%eax
mov    0x2cbb(%rip),%rcx
movsbl (%rcx),%ecx
cmp    %ecx,%eax
setne  %al
mov    %al,-0x23(%rbp)
mov    -0x23(%rbp),%al
test   $0x1,%al
jne    1348 <main+0x1b8>
jmp    134d <main+0x1bd>
jmp    1307 <main+0x177>
jmp    12e0 <main+0x150>
jmp    1357 <main+0x1c7>
mov    $0x0,%al
call   1080 <getchar@plt>
mov    %al,-0x22(%rbp)
movsbl %al,%ecx
xor    %eax,%eax
cmp    $0xa,%ecx
mov    %al,-0x24(%rbp)
je     1388 <main+0x1f8>
movsbl -0x22(%rbp),%eax
mov    0x2c6b(%rip),%rcx
movsbl (%rcx),%ecx
cmp    %ecx,%eax
setne  %al
mov    %al,-0x24(%rbp)
mov    -0x24(%rbp),%al
test   $0x1,%al
jne    1398 <main+0x208>
jmp    139d <main+0x20d>
jmp    1357 <main+0x1c7>
movsbl -0x21(%rbp),%edi
call   10a0 <tolower@plt>
movsbl %al,%eax
cmp    $0x79,%eax
je     13cb <main+0x23b>
mov    -0x18(%rbp),%esi
mov    -0x1c(%rbp),%edx
lea    0xc9b(%rip),%rdi
mov    $0x0,%al
call   1050 <printf@plt>
jmp    13d0 <main+0x240>
jmp    11dd <main+0x4d>
mov    $0x0,%al
call   1080 <getchar@plt>
mov    0x2bfa(%rip),%rax
mov    (%rax),%eax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x18,%rsp
xor    %edi,%edi
call   10a0 <time@plt>
mov    %eax,%edi
call   1080 <srand@plt>
lea    0xe3d(%rip),%r14
lea    0xe46(%rip),%r12
lea    0xf(%rsp),%rbx
mov    0x2e12(%rip),%r13
lea    0xe4c(%rip),%r15
movl   $0x0,0x14(%rsp)
movl   $0x0,0x10(%rsp)
jmp    1202 <main+0x62>
nop
movsbl 0xf(%rsp),%edi
call   10b0 <tolower@plt>
cmp    $0x79,%al
jne    12fa <main+0x15a>
mov    $0x2,%edi
call   1040 <RollDiceSum@plt>
mov    %eax,%ebp
mov    %r14,%rdi
mov    %eax,%esi
xor    %eax,%eax
call   1060 <printf@plt>
cmp    $0x7,%ebp
je     1280 <main+0xe0>
mov    $0x2,%edi
call   1040 <RollDiceSum@plt>
mov    %eax,%ebp
mov    %r14,%rdi
mov    %eax,%esi
xor    %eax,%eax
call   1060 <printf@plt>
cmp    $0xc,%ebp
ja     1260 <main+0xc0>
mov    $0x100c,%eax
bt     %ebp,%eax
jb     1280 <main+0xe0>
mov    $0x880,%eax
bt     %ebp,%eax
jae    1260 <main+0xc0>
xor    %eax,%eax
call   1030 <OnWin@plt>
addl   $0x1,0x14(%rsp)
jmp    128c <main+0xec>
xchg   %ax,%ax
mov    $0x2,%edi
call   1040 <RollDiceSum@plt>
mov    %eax,%ebp
mov    %r14,%rdi
mov    %eax,%esi
xor    %eax,%eax
call   1060 <printf@plt>
cmp    $0x7,%ebp
jne    1260 <main+0xc0>
nopl   (%rax)
xor    %eax,%eax
call   1070 <OnLose@plt>
addl   $0x1,0x10(%rsp)
movb   $0x0,0xf(%rsp)
lea    0xdb2(%rip),%rdi
call   1050 <puts@plt>
nopl   (%rax)
mov    %r12,%rdi
mov    %rbx,%rsi
call   10c0 <scanf@plt>
cmp    $0x1,%eax
je     12e0 <main+0x140>
mov    %r15,%rdi
call   1050 <puts@plt>
nopl   0x0(%rax,%rax,1)
xor    %eax,%eax
call   1090 <getchar@plt>
cmp    $0xa,%al
je     12a0 <main+0x100>
cmp    0x0(%r13),%al
jne    12c0 <main+0x120>
jmp    12a0 <main+0x100>
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
xor    %eax,%eax
call   1090 <getchar@plt>
cmp    $0xa,%al
je     11f0 <main+0x50>
cmp    0x0(%r13),%al
jne    12e0 <main+0x140>
jmp    11f0 <main+0x50>
lea    0xd13(%rip),%rdi
mov    0x14(%rsp),%esi
mov    0x10(%rsp),%edx
xor    %eax,%eax
call   1060 <printf@plt>
xor    %eax,%eax
call   1090 <getchar@plt>
mov    0x2cba(%rip),%rax
mov    (%rax),%eax
add    $0x18,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@.str = [16 x i8] c"You rolled %d.\0A\00"
@.str.1 = [37 x i8] c"Would you like to play again? (y/n)\0A\00"
@.str.2 = [4 x i8] c" %c\00"
@.str.3 = [70 x i8] c"I am sorry, didn't quite get it.\0AWould you like to play again? (y/n)\0A\00"
@EOF = global i8 0
@.str.4 = [21 x i8] c"%d wins, %d losses.\0A\00"
@EXIT_SUCCESS = global i32 0
define i32 @main() {
%1 = alloca i32
%2 = alloca i32
%3 = alloca i32
%4 = alloca i32
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
%9 = alloca i8
%10 = alloca i8
store i32 0, i32* %1
%11 = call i64 @time(i32* null)
%12 = trunc i64 %11 to i32
store i32 %12, i32* %2
%13 = load i32, i32* %2
%14 = call i32 @srand(i32 %13)
store i32 0, i32* %3
store i32 0, i32* %4
store i32 2, i32* %5
store i32 0, i32* %6
store i32 0, i32* %7
store i32 0, i32* %8
br label %15
15: ; preds = %0, %107
store i32 0, i32* %8
store i32 0, i32* %3
br label %16
16: ; preds = %60, %15
%17 = load i32, i32* %8
%18 = icmp ne i32 %17, 0
%19 = xor i1 %18, true
br i1 %19, label %20, label %63
20: ; preds = %16
%21 = load i32, i32* %5
%22 = call i32 @RollDiceSum(i32 %21)
store i32 %22, i32* %4
%23 = load i32, i32* %4
%24 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str, i64 0, i64 0), i32 %23)
%25 = load i32, i32* %3
%26 = icmp eq i32 %25, 1
br i1 %26, label %27, label %52
27: ; preds = %20
%28 = load i32, i32* %4
%29 = icmp eq i32 %28, 7
br i1 %29, label %33, label %30
30: ; preds = %27
%31 = load i32, i32* %4
%32 = icmp eq i32 %31, 11
br i1 %32, label %33, label %37
33: ; preds = %30, %27
%34 = call i32 (...) @OnWin()
%35 = load i32, i32* %6
%36 = add nsw i32 %35, 1
store i32 %36, i32* %6
store i32 1, i32* %8
br label %51
37: ; preds = %30
%38 = load i32, i32* %4
%39 = icmp eq i32 %38, 2
br i1 %39, label %46, label %40
40: ; preds = %37
%41 = load i32, i32* %4
%42 = icmp eq i32 %41, 3
br i1 %42, label %46, label %43
43: ; preds = %40
%44 = load i32, i32* %4
%45 = icmp eq i32 %44, 12
br i1 %45, label %46, label %50
46: ; preds = %43, %40, %37
%47 = call i32 (...) @OnLose()
%48 = load i32, i32* %7
%49 = add nsw i32 %48, 1
store i32 %49, i32* %7
store i32 1, i32* %8
br label %50
50: ; preds = %46, %43
br label %51
51: ; preds = %50, %33
br label %60
52: ; preds = %20
%53 = load i32, i32* %4
%54 = icmp eq i32 %53, 7
br i1 %54, label %55, label %59
55: ; preds = %52
%56 = call i32 (...) @OnLose()
%57 = load i32, i32* %7
%58 = add nsw i32 %57, 1
store i32 %58, i32* %7
store i32 1, i32* %8
br label %59
59: ; preds = %55, %52
br label %60
60: ; preds = %59, %51
%61 = load i32, i32* %3
%62 = add nsw i32 %61, 1
store i32 %62, i32* %3
br label %16
63: ; preds = %16
store i8 0, i8* %9
store i8 0, i8* %10
%64 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([37 x i8], [37 x i8]* @.str.1, i64 0, i64 0))
br label %65
65: ; preds = %83, %63
%66 = call i32 @scanf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.2, i64 0, i64 0), i8* %9)
%67 = icmp ne i32 %66, 1
br i1 %67, label %68, label %84
68: ; preds = %65
%69 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([70 x i8], [70 x i8]* @.str.3, i64 0, i64 0))
br label %70
70: ; preds = %82, %68
%71 = call signext i8 (...) @getchar()
store i8 %71, i8* %10
%72 = sext i8 %71 to i32
%73 = icmp ne i32 %72, 10
br i1 %73, label %74, label %80
74: ; preds = %70
%75 = load i8, i8* %10
%76 = sext i8 %75 to i32
%77 = load i8, i8* @EOF
%78 = sext i8 %77 to i32
%79 = icmp ne i32 %76, %78
br label %80
80: ; preds = %74, %70
%81 = phi i1 [ false, %70 ], [ %79, %74 ]
br i1 %81, label %82, label %83
82: ; preds = %80
br label %70
83: ; preds = %80
br label %65
84: ; preds = %65
br label %85
85: ; preds = %97, %84
%86 = call signext i8 (...) @getchar()
store i8 %86, i8* %10
%87 = sext i8 %86 to i32
%88 = icmp ne i32 %87, 10
br i1 %88, label %89, label %95
89: ; preds = %85
%90 = load i8, i8* %10
%91 = sext i8 %90 to i32
%92 = load i8, i8* @EOF
%93 = sext i8 %92 to i32
%94 = icmp ne i32 %91, %93
br label %95
95: ; preds = %89, %85
%96 = phi i1 [ false, %85 ], [ %94, %89 ]
br i1 %96, label %97, label %98
97: ; preds = %95
br label %85
98: ; preds = %95
%99 = load i8, i8* %9
%100 = call signext i8 @tolower(i8 signext %99)
%101 = sext i8 %100 to i32
%102 = icmp ne i32 %101, 121
br i1 %102, label %103, label %107
103: ; preds = %98
%104 = load i32, i32* %6
%105 = load i32, i32* %7
%106 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str.4, i64 0, i64 0), i32 %104, i32 %105)
br label %108
107: ; preds = %98
br label %15
108: ; preds = %103
%109 = call signext i8 (...) @getchar()
%110 = load i32, i32* @EXIT_SUCCESS
ret i32 %110
}

LLVM IR (-O2):
@.str = [16 x i8] c"You rolled %d.\0A\00"
@.str.2 = [4 x i8] c" %c\00"
@EOF = global i8 0
@.str.4 = [21 x i8] c"%d wins, %d losses.\0A\00"
@EXIT_SUCCESS = global i32 0
@str = [36 x i8] c"Would you like to play again? (y/n)\00"
@str.5 = [69 x i8] c"I am sorry, didn't quite get it.\0AWould you like to play again? (y/n)\00"
define i32 @main() {
%1 = alloca i8
%2 = tail call i64 @time(i32* null)
%3 = trunc i64 %2 to i32
%4 = tail call i32 @srand(i32 %3)
br label %5
5: ; preds = %0, %58
%6 = phi i32 [ 0, %0 ], [ %31, %58 ]
%7 = phi i32 [ 0, %0 ], [ %32, %58 ]
%8 = call i32 @RollDiceSum(i32 2)
%9 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([16 x i8], [16 x i8]* @.str, i64 0, i64 0), i32 %8)
%10 = icmp eq i32 %8, 7
br i1 %10, label %11, label %14
11: ; preds = %5
%12 = call i32 (...) @OnLose()
%13 = add nsw i32 %7, 1
br label %30
14: ; preds = %5
%15 = call i32 @RollDiceSum(i32 2)
%16 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([16 x i8], [16 x i8]* @.str, i64 0, i64 0), i32 %15)
switch i32 %15, label %23 [
i32 11, label %20
i32 7, label %20
i32 12, label %17
i32 3, label %17
i32 2, label %17
]
17: ; preds = %14, %14, %14
%18 = call i32 (...) @OnLose()
%19 = add nsw i32 %7, 1
br label %30
20: ; preds = %14, %14
%21 = call i32 (...) @OnWin()
%22 = add nsw i32 %6, 1
br label %30
23: ; preds = %14, %23
%24 = call i32 @RollDiceSum(i32 2)
%25 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([16 x i8], [16 x i8]* @.str, i64 0, i64 0), i32 %24)
%26 = icmp eq i32 %24, 7
br i1 %26, label %27, label %23
27: ; preds = %23
%28 = call i32 (...) @OnLose()
%29 = add nsw i32 %7, 1
br label %30
30: ; preds = %17, %20, %11, %27
%31 = phi i32 [ %6, %11 ], [ %6, %27 ], [ %6, %17 ], [ %22, %20 ]
%32 = phi i32 [ %13, %11 ], [ %29, %27 ], [ %19, %17 ], [ %7, %20 ]
store i8 0, i8* %1
%33 = call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([36 x i8], [36 x i8]* @str, i64 0, i64 0))
%34 = call i32 @scanf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.2, i64 0, i64 0), i8* %1)
%35 = icmp eq i32 %34, 1
br i1 %35, label %36, label %40
36: ; preds = %37, %30
br label %48
37: ; preds = %42
%38 = call i32 @scanf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.2, i64 0, i64 0), i8* %1)
%39 = icmp eq i32 %38, 1
br i1 %39, label %36, label %40
40: ; preds = %30, %37
%41 = call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([69 x i8], [69 x i8]* @str.5, i64 0, i64 0))
br label %42
42: ; preds = %42, %40
%43 = call signext i8 (...) @getchar()
%44 = icmp ne i8 %43, 10
%45 = load i8, i8* @EOF
%46 = icmp ne i8 %43, %45
%47 = select i1 %44, i1 %46, i1 false
br i1 %47, label %42, label %37
48: ; preds = %36, %48
%49 = call signext i8 (...) @getchar()
%50 = icmp ne i8 %49, 10
%51 = load i8, i8* @EOF
%52 = icmp ne i8 %49, %51
%53 = select i1 %50, i1 %52, i1 false
br i1 %53, label %48, label %54
54: ; preds = %48
%55 = load i8, i8* %1
%56 = call signext i8 @tolower(i8 signext %55)
%57 = icmp eq i8 %56, 121
br i1 %57, label %58, label %59
58: ; preds = %54
br label %5
59: ; preds = %54
%60 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([21 x i8], [21 x i8]* @.str.4, i64 0, i64 0), i32 %31, i32 %32)
%61 = call signext i8 (...) @getchar()
%62 = load i32, i32* @EXIT_SUCCESS
ret i32 %62
}