// File: /workspace/github_c_makefile_star2_O1/PARKINHYO[P]BlackjackGame/fifo/fifo_server.c
// Function: play_game_one
void* play_game_one(void *data)
{
  int gnSemID2;      /* Semapore Indicator */
  int id = (intptr_t)data;
  int shmId = (intptr_t)data + 60100;
  int semId = (intptr_t)data+1 +60100;
  char buffer[BUFFER_SIZE];
  int nwritten;
  int player_sum, dealer_sum;
  int *player_hand_values = players_hand_values[id], *dealer_hand_values = dealers_hand_values[id];
  int *player_hand_suits = players_hand_suits[id], *dealer_hand_suits = dealers_hand_suits[id];
  int i;

  /* Semapore */
  key_t keySem;       /* Semapore Key */
  union semun sem_union;
  struct sembuf mysem_open  = {0, -1, SEM_UNDO}; // 세마포어 얻기
  struct sembuf mysem_close = {0, 1, SEM_UNDO};  // 세마포어 돌려주기

  /* Semapore 키값을 생성한다. */
  keySem = (key_t)semId;

  /* 공유 Semapore 세그먼트를 연다 - 필요하면 만든다. */
  if((gnSemID2 = semget( keySem, 1, IPC_CREAT | IPC_EXCL | 0666 )) == -1)
  {
   // printf("[SERVER]Semapore segment exist - opening as client\n");
    /* 세그먼트가 이미 존재한다면 - try as a client */
    if( (gnSemID2 = semget( keySem, 0, 0 )) == -1 )
    {
      perror("semget");
      exit(1);
    }
  }
  else
  {
   // printf("[SERVER]Creating new semapore segment\n");
  }

  /* Semapore 초기화 */
  sem_union.val = 1;
  semctl( gnSemID2, 0, SETVAL, sem_union );

  /*첫 카드 뽑기*/
  nplayers[id] = 0;
	ndealers[id] = 0;
  /*딜러들의 카드덱은 공유 - mutex로 raceCondition 제어*/
  pthread_mutex_lock(&card_mutex);
	{
		for (i = 0; i < 2; ++i)
		{
			player_hand_values[nplayers[id]] = card_values[ncard];
			player_hand_suits[nplayers[id]] = card_suits[ncard];
			++ncard;
			++nplayers[id];
		}

		dealer_hand_values[ndealers[id]] = card_values[ncard];
		dealer_hand_suits[ndealers[id]] = card_suits[ncard];
		++ncard;
		++ndealers[id];
	}
	pthread_mutex_unlock(&card_mutex);

  buffer[0] = value_codes[player_hand_values[0]];
	buffer[1] = suit_codes[player_hand_suits[0]];
	buffer[2] = value_codes[player_hand_values[1]];
	buffer[3] = suit_codes[player_hand_suits[1]];
	buffer[4] = value_codes[dealer_hand_values[0]];
	buffer[5] = suit_codes[dealer_hand_suits[0]];
	buffer[6] = 0;

  /******* 임계영역 *******/
  if( semop(gnSemID2, &mysem_open, 1) == -1 )
	{
		perror("semop");
		exit(1);
	}

  //client[id-1]로 카드 줌 )
	write(client[id - 1], buffer, BUFFER_SIZE);

	printf("[SERVER] send to player[%d]: first cardset\n",id);

  semop(gnSemID2, &mysem_close, 1);
  /******* 임계영역 *******/

  /* 첫 카드를 주고서*/
  printf("\n");
  printf("[SERVER] Player[%d] Hand: ",id );
  display_state(player_hand_values, player_hand_suits, nplayers[id]);
  printf("[SERVER] Dealer Hand with player[%d]: ",id);
  display_state(dealer_hand_values, dealer_hand_suits, ndealers[id]);

  //HIT STAND 받을 파이프 open
  clientRead[id - 1] = open(filename2, O_RDWR);

  while (TRUE) {
	  sleep(1);
	  //HIT / STAND 받음
	  read(clientRead[id - 1], buffer, BUFFER_SIZE);
	  printf("[SERVER] I received from player[%d]: %s\n", id, buffer);

	  //HIT일때
	  if (strcmp(buffer, HIT) == 0)
	  {
		  pthread_mutex_lock(&card_mutex);
		  {
			  player_hand_values[nplayers[id]] = card_values[ncard];
			  player_hand_suits[nplayers[id]] = card_suits[ncard];

			  buffer[0] = value_codes[player_hand_values[nplayers[id]]];
			  buffer[1] = suit_codes[player_hand_suits[nplayers[id]]];
			  buffer[2] = 0;

			  ++ncard;
			  ++nplayers[id];
		  }
		  pthread_mutex_unlock(&card_mutex);

		  //새로운 카드 클라이언트로 보냄
		  write(client[id - 1], buffer, BUFFER_SIZE);
		  printf("[SERVER] I send to player[%d]: %s\n", id, buffer);

		  check2[0] = 1;
		  buffer[0] = '\0';
		  semop(gnSemID2, &mysem_close, 1);

		  /* 플레이어 결과가 21이 넘을 경우*/
		  if (calc_sum(player_hand_values, nplayers[id]) > 21)
		  {
			  printf("[SERVER] Player[%d] busted. Dealer wins.\n", id);
			  return NULL;
		  }
		  /* 플레이어 결과가 21일 경우 이기기 때문에 break */
		  else if (calc_sum(player_hand_values, nplayers[id]) == 21)
			  break;
	  } //여기까지 HIT 처리

	  //STAND 일때 - break
	  else if (strcmp(buffer, STAND) == 0) {
		  check2[0] = 1;
		  semop(gnSemID2, &mysem_close, 1);
		  break;
	  }
  }
  i=0;
  while (calc_sum(dealer_hand_values, ndealers[id]) < 17)
  {
    dealer_hand_values[ndealers[id]] = card_values[ncard];
    dealer_hand_suits[ndealers[id]] = card_suits[ncard];
    buffer[i++] = value_codes[dealer_hand_values[ndealers[id]]];
    buffer[i++] = suit_codes[dealer_hand_suits[ndealers[id]]];
    ++ncard;
    ++ndealers[id];
  }
  buffer[i] = 0;

  printf("\n");
  printf("[SERVER] Player[%d] Hand: ",id);
  display_state(player_hand_values, player_hand_suits, nplayers[id]);
  printf("[SERVER] Dealer Hand with Player[%d]: ",id);
  display_state(dealer_hand_values, dealer_hand_suits, ndealers[id]);

  if( semop(gnSemID2, &mysem_open, 1) == -1 )
  {
          perror("semop");
          exit(1);
  }
  //카드 보냄
  write(client[id - 1], buffer, BUFFER_SIZE);


  player_sum = calc_sum(player_hand_values, nplayers[id]);
  dealer_sum = calc_sum(dealer_hand_values, ndealers[id]);

  //결과
  if (dealer_sum > 21)
    printf("\n[SERVER] Dealer busted! Player[%d] wins!\n", id);
  else if (player_sum == dealer_sum)
    printf("\n[SERVER] Player[%d] and dealer have the SAME score. It's a push!\n", id);
  else if (player_sum < dealer_sum)
    printf("\n[SERVER] Dealer has a higher score than player[%d]. Dealer wins!\n", id);
  else
    printf("\n[SERVER] Player[%d] has a higher score. Player wins!\n", id);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
movq %rdi, -0x38(%rbp)
leal 0xeac5(%rdi), %r14d
movw $0x1000, %ax            # imm = 0x1000
movw %ax, -0x44(%rbp)
movl $0xffff0000, -0x48(%rbp) # imm = 0xFFFF0000
movw %ax, -0x3c(%rbp)
movl $0x10000, -0x40(%rbp)   # imm = 0x10000
movl %r14d, %edi
movl $0x1, %esi
movl $0x7b6, %edx            # imm = 0x7B6
callq 0x1030
cmpl $-0x1, %eax
jne 0x180e
movl %r14d, %edi
xorl %esi, %esi
xorl %edx, %edx
callq 0x1030
cmpl $-0x1, %eax
je 0x1e3d
movslq -0x38(%rbp), %r14
movq %r14, %rcx
shlq $0x4, %rcx
leaq (%rcx,%rcx,4), %r12
leaq 0x2bbc(%rip), %r13      # 0x43e0
addq %r12, %r13
leaq 0x2d42(%rip), %rcx      # 0x4570
addq %r12, %rcx
movq %rcx, -0x78(%rbp)
leaq 0x2ec4(%rip), %r15      # 0x4700
addq %r12, %r15
leaq 0x304a(%rip), %rcx      # 0x4890
addq %rcx, %r12
movl $0x1, %ecx
movl %eax, %edi
movl %eax, -0x2c(%rbp)
xorl %esi, %esi
movl $0x10, %edx
xorl %eax, %eax
callq 0x1130
leaq 0x31b8(%rip), %rbx      # 0x4a20
xorl %ecx, %ecx
movl %ecx, (%rbx,%r14,4)
leaq 0x31cb(%rip), %rax      # 0x4a40
movl %ecx, (%rax,%r14,4)
leaq 0x31d8(%rip), %rdi      # 0x4a58
callq 0x1190
movslq 0x2b44(%rip), %rax      # 0x43d0
movslq (%rbx,%r14,4), %rcx
leaq 0x2999(%rip), %rsi      # 0x4230
movq (%rsi,%rax,4), %rdx
movq %rdx, (%r13,%rcx,4)
leaq 0x2a59(%rip), %rdi      # 0x4300
movq (%rdi,%rax,4), %rdx
movq %rdx, (%r15,%rcx,4)
leal 0x2(%rax), %edx
addl $0x2, %ecx
movl %edx, 0x2b15(%rip)      # 0x43d0
movl %ecx, (%rbx,%r14,4)
movslq %edx, %rcx
movl (%rsi,%rcx,4), %edx
leaq 0x3174(%rip), %r8       # 0x4a40
movslq (%r8,%r14,4), %rsi
movq -0x78(%rbp), %rbx
movl %edx, (%rbx,%rsi,4)
movl (%rdi,%rcx,4), %ecx
movl %ecx, (%r12,%rsi,4)
addl $0x3, %eax
movl %eax, 0x2ae9(%rip)      # 0x43d0
leal 0x1(%rsi), %eax
movl %eax, (%r8,%r14,4)
leaq 0x3163(%rip), %rdi      # 0x4a58
callq 0x10e0
movslq (%r13), %rax
leaq 0xa55(%rip), %rdx       # 0x235a
movb (%rax,%rdx), %al
movb %al, -0x70(%rbp)
movslq (%r15), %rax
leaq 0xa41(%rip), %rcx       # 0x2356
movb (%rax,%rcx), %al
movb %al, -0x6f(%rbp)
movq %r13, -0x80(%rbp)
movslq 0x4(%r13), %rax
movb (%rax,%rdx), %al
movb %al, -0x6e(%rbp)
movq %r15, -0x88(%rbp)
movslq 0x4(%r15), %rax
movb (%rax,%rcx), %al
movb %al, -0x6d(%rbp)
movslq (%rbx), %rax
movb (%rax,%rdx), %al
movb %al, -0x6c(%rbp)
movslq (%r12), %rax
movb (%rax,%rcx), %al
movb %al, -0x6b(%rbp)
movb $0x0, -0x6a(%rbp)
leaq -0x48(%rbp), %rsi
movl $0x1, %edx
movl -0x2c(%rbp), %edi
callq 0x1140
cmpl $-0x1, %eax
je 0x1e33
movq -0x38(%rbp), %r15
movq %r15, %rax
shlq $0x20, %rax
movabsq $-0x100000000, %r13     # imm = 0xFFFFFFFF00000000
addq %rax, %r13
movq %r13, %rax
sarq $0x20, %rax
movq %rax, -0x90(%rbp)
sarq $0x1e, %r13
leaq 0x2884(%rip), %rax      # 0x4220
movl (%r13,%rax), %edi
leaq -0x70(%rbp), %rsi
movl $0x20, %edx
callq 0x1060
leaq 0x71c(%rip), %rdi       # 0x20d2
movl %r15d, %esi
xorl %eax, %eax
callq 0x1070
leaq -0x40(%rbp), %rsi
movl $0x1, %edx
movl -0x2c(%rbp), %edi
callq 0x1140
movl $0xa, %edi
callq 0x1040
leaq 0x71c(%rip), %rdi       # 0x20fe
movl %r15d, %esi
xorl %eax, %eax
callq 0x1070
leaq 0x302d(%rip), %rax      # 0x4a20
movl (%rax,%r14,4), %edx
movq -0x80(%rbp), %rdi
movq -0x88(%rbp), %rsi
callq 0x13f0
leaq 0x70b(%rip), %rdi       # 0x2119
movl %r15d, %esi
xorl %eax, %eax
callq 0x1070
leaq 0x3021(%rip), %rax      # 0x4a40
movl (%rax,%r14,4), %edx
movq %rbx, %rdi
movq %r12, %rsi
callq 0x13f0
leaq 0x27cb(%rip), %rdi      # 0x4200
movl $0x2, %esi
xorl %eax, %eax
callq 0x1110
leaq 0x3038(%rip), %r15      # 0x4a80
movl %eax, (%r13,%r15)
movq -0x90(%rbp), %r13
movq %r12, -0x98(%rbp)
leaq 0x27ce(%rip), %r12      # 0x4230
movq %r14, %rbx
leaq -0x70(%rbp), %r14
movq %rbx, -0xc0(%rbp)
movl $0x1, %edi
callq 0x1180
movl (%r15,%r13,4), %edi
movl $0x20, %edx
movq %r14, %rsi
callq 0x1080
leaq 0x6ae(%rip), %rdi       # 0x2140
movq -0x38(%rbp), %rsi
movq %r14, %rdx
xorl %eax, %eax
callq 0x1070
cmpl $0x544948, -0x70(%rbp)  # imm = 0x544948
jne 0x1bc5
leaq 0x2fa4(%rip), %r15      # 0x4a58
movq %r15, %rdi
callq 0x1190
movslq 0x290d(%rip), %rax      # 0x43d0
movslq (%r12,%rax,4), %rcx
leaq 0x2f52(%rip), %r12      # 0x4a20
movslq (%r12,%rbx,4), %rdx
movq %r12, %r8
movq %r14, %r12
movq -0x38(%rbp), %r14
movq -0x80(%rbp), %rsi
movl %ecx, (%rsi,%rdx,4)
leaq 0x2816(%rip), %rsi      # 0x4300
movslq (%rsi,%rax,4), %rsi
movq -0x88(%rbp), %rdi
movl %esi, (%rdi,%rdx,4)
leaq 0x85b(%rip), %rdi       # 0x235a
movb (%rcx,%rdi), %cl
movb %cl, -0x70(%rbp)
leaq 0x84a(%rip), %rcx       # 0x2356
movb (%rsi,%rcx), %cl
movb %cl, -0x6f(%rbp)
xorl %ecx, %ecx
movb %cl, -0x6e(%rbp)
incl %eax
movl %eax, 0x28b1(%rip)      # 0x43d0
leal 0x1(%rdx), %eax
movl %eax, (%r8,%rbx,4)
movq %r15, %rdi
callq 0x10e0
movq %r13, %rbx
leaq 0x26e8(%rip), %rax      # 0x4220
movl (%rax,%r13,4), %edi
movl $0x20, %edx
movq %r12, %rsi
callq 0x1060
leaq 0x619(%rip), %rdi       # 0x2169
movl %r14d, %esi
movq %r12, %r15
movq %r12, %rdx
xorl %eax, %eax
callq 0x1070
movl $0x1, 0x2f22(%rip)      # 0x4a8c
xorl %eax, %eax
movb %al, -0x70(%rbp)
movl $0x1, %edx
movl -0x2c(%rbp), %edi
leaq -0x40(%rbp), %rsi
callq 0x1140
movq -0xc0(%rbp), %rax
movq %rax, %r14
leaq 0x2e8f(%rip), %rcx      # 0x4a20
movl (%rcx,%rax,4), %esi
movq -0x80(%rbp), %rdi
callq 0x139b
cmpl $0x15, %eax
jg 0x1d0c
leaq 0x2683(%rip), %r12      # 0x4230
movq %rbx, %r13
movq %r14, %rbx
movq %r15, %r14
leaq 0x2ec3(%rip), %r15      # 0x4a80
jne 0x1a70
jmp 0x1bf9
movl -0x70(%rbp), %eax
movl $0x4e415453, %ecx       # imm = 0x4E415453
xorl %ecx, %eax
movzwl -0x6c(%rbp), %ecx
xorl $0x44, %ecx
orl %eax, %ecx
jne 0x1a70
movl $0x1, 0x2ea4(%rip)      # 0x4a8c
leaq -0x40(%rbp), %rsi
movl $0x1, %edx
movl -0x2c(%rbp), %edi
callq 0x1140
leaq 0x2e40(%rip), %r13      # 0x4a40
movl (%r13,%rbx,4), %esi
movq -0x78(%rbp), %rdi
movq %rsi, %r14
callq 0x139b
cmpl $0x10, %eax
jg 0x1d18
movslq %r14d, %rax
movslq 0x27ac(%rip), %r13      # 0x43d0
leal 0x1(%r13), %ecx
movq %rcx, -0xb0(%rbp)
shlq $0x2, %r13
movq %r13, -0xa8(%rbp)
leaq (%rbx,%rbx,4), %rcx
shlq $0x4, %rcx
leaq (%rcx,%rax,4), %rax
movq %rax, -0xa0(%rbp)
incl %r14d
movq %r14, -0xb8(%rbp)
xorl %r14d, %r14d
movq %rbx, %r12
leaq 0x6f6(%rip), %r13       # 0x235a
xorl %ebx, %ebx
movq -0x78(%rbp), %r15
movq -0xa8(%rbp), %rax
leaq (%rax,%r14,4), %rax
leaq 0x25b4(%rip), %rcx      # 0x4230
movslq (%rcx,%rax), %rcx
movq -0xa0(%rbp), %rdx
leaq (%rdx,%r14,4), %rdx
leaq 0x28de(%rip), %rsi      # 0x4570
movl %ecx, (%rsi,%rdx)
leaq 0x2664(%rip), %rsi      # 0x4300
movslq (%rsi,%rax), %rax
leaq 0x2be9(%rip), %rsi      # 0x4890
movl %eax, (%rsi,%rdx)
movb (%rcx,%r13), %cl
movb %cl, -0x70(%rbp,%r14,2)
leaq 0x69c(%rip), %rcx       # 0x2356
movb (%rax,%rcx), %al
addq $0x2, %rbx
movb %al, -0x6f(%rbp,%r14,2)
movq -0xb0(%rbp), %rax
addl %r14d, %eax
movl %eax, 0x26fa(%rip)      # 0x43d0
movq -0xb8(%rbp), %rax
leal (%rax,%r14), %esi
leaq 0x2d58(%rip), %rax      # 0x4a40
movl %esi, (%rax,%r12,4)
movq %r15, %rdi
callq 0x139b
incq %r14
cmpl $0x11, %eax
jl 0x1c6a
andl $-0x2, %ebx
leaq 0x2d36(%rip), %r13      # 0x4a40
jmp 0x1d1d
leaq 0x479(%rip), %rdi       # 0x218c
jmp 0x1e14
movq %rbx, %r12
xorl %ebx, %ebx
movb $0x0, -0x70(%rbp,%rbx)
movl $0xa, %edi
callq 0x1040
leaq 0x3cb(%rip), %rdi       # 0x20fe
movq -0x38(%rbp), %r15
movl %r15d, %esi
xorl %eax, %eax
callq 0x1070
movq %r12, %rbx
leaq 0x2cd5(%rip), %rax      # 0x4a20
movl (%rax,%r12,4), %edx
movq -0x80(%rbp), %r14
movq %r14, %rdi
movq -0x88(%rbp), %rsi
callq 0x13f0
leaq 0x453(%rip), %rdi       # 0x21bc
movl %r15d, %esi
xorl %eax, %eax
callq 0x1070
movl (%r13,%r12,4), %edx
movq -0x78(%rbp), %r12
movq %r12, %rdi
movq -0x98(%rbp), %rsi
callq 0x13f0
leaq -0x48(%rbp), %rsi
movl $0x1, %edx
movl -0x2c(%rbp), %edi
callq 0x1140
cmpl $-0x1, %eax
je 0x1e38
movq -0x90(%rbp), %rax
leaq 0x246d(%rip), %rcx      # 0x4220
movl (%rcx,%rax,4), %edi
leaq -0x70(%rbp), %rsi
movl $0x20, %edx
callq 0x1060
leaq 0x2c55(%rip), %rax      # 0x4a20
movl (%rax,%rbx,4), %esi
movq %r14, %rdi
callq 0x139b
movl %eax, %r14d
movl (%r13,%rbx,4), %esi
movq %r12, %rdi
callq 0x139b
cmpl $0x15, %eax
jle 0x1df4
leaq 0x3f1(%rip), %rdi       # 0x21e3
jmp 0x1e14
cmpl %eax, %r14d
jne 0x1e02
leaq 0x40e(%rip), %rdi       # 0x220e
jmp 0x1e14
leaq 0x448(%rip), %rax       # 0x2251
leaq 0x484(%rip), %rdi       # 0x2294
cmovlq %rax, %rdi
movq -0x38(%rbp), %rsi
xorl %eax, %eax
callq 0x1070
xorl %eax, %eax
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x1208
callq 0x11f0
callq 0x1220