// File: /workspace/github_c_makefile_star2_O3/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, %r15
leal 0xeac5(%rdi), %r14d
movw $0x1000, %ax            # imm = 0x1000
movw %ax, -0x54(%rbp)
movl $0xffff0000, -0x58(%rbp) # imm = 0xFFFF0000
movw %ax, -0x30(%rbp)
movl $0x10000, -0x34(%rbp)   # imm = 0x10000
movl %r14d, %edi
movl $0x1, %esi
movl $0x7b6, %edx            # imm = 0x7B6
callq 0x1030
cmpl $-0x1, %eax
jne 0x180d
movl %r14d, %edi
xorl %esi, %esi
xorl %edx, %edx
callq 0x1030
cmpl $-0x1, %eax
je 0x1e63
movslq %r15d, %r13
movq %r13, %rcx
shlq $0x4, %rcx
leaq (%rcx,%rcx,4), %rbx
leaq 0x2bbe(%rip), %rcx      # 0x43e0
addq %rbx, %rcx
movq %rcx, -0x50(%rbp)
leaq 0x2d40(%rip), %rcx      # 0x4570
addq %rbx, %rcx
movq %rcx, -0x40(%rbp)
movq %r15, -0x48(%rbp)
leaq 0x2ebe(%rip), %rcx      # 0x4700
leaq (%rcx,%rbx), %r12
leaq 0x3043(%rip), %rcx      # 0x4890
addq %rcx, %rbx
xorl %r15d, %r15d
movl $0x1, %ecx
movl %eax, %edi
movl %eax, -0x2c(%rbp)
xorl %esi, %esi
movl $0x10, %edx
xorl %eax, %eax
callq 0x1130
leaq 0x31ae(%rip), %r14      # 0x4a20
movl %r15d, (%r14,%r13,4)
leaq 0x31c3(%rip), %rax      # 0x4a40
movl %r15d, (%rax,%r13,4)
leaq 0x31d0(%rip), %rdi      # 0x4a58
callq 0x1190
movslq 0x2b3c(%rip), %rax      # 0x43d0
movslq (%r14,%r13,4), %rcx
leaq (,%r13,4), %rdx
addq %r13, %rdx
shlq $0x4, %rdx
movq %rdx, -0x90(%rbp)
leaq (%rdx,%rcx,4), %rdx
leaq 0x2977(%rip), %rdi      # 0x4230
movq (%rdi,%rax,4), %rsi
leaq 0x2b1c(%rip), %r8       # 0x43e0
movq %rsi, (%r8,%rdx)
movq %r13, %r15
movq -0x40(%rbp), %r13
leaq 0x2a2a(%rip), %r8       # 0x4300
movq (%r8,%rax,4), %rsi
leaq 0x2e1f(%rip), %r9       # 0x4700
movq %rsi, (%r9,%rdx)
leal 0x2(%rax), %edx
leal 0x2(%rcx), %ecx
movl %ecx, (%r14,%r15,4)
movslq %edx, %rcx
movl (%rdi,%rcx,4), %edx
leaq 0x3144(%rip), %rdi      # 0x4a40
movslq (%rdi,%r15,4), %rsi
movl %edx, (%r13,%rsi,4)
movl (%r8,%rcx,4), %ecx
movl %ecx, (%rbx,%rsi,4)
addl $0x3, %eax
movl %eax, 0x2abb(%rip)      # 0x43d0
leal 0x1(%rsi), %eax
movl %eax, (%rdi,%r15,4)
leaq 0x3135(%rip), %rdi      # 0x4a58
callq 0x10e0
movq -0x50(%rbp), %rdx
movslq (%rdx), %rax
leaq 0xa24(%rip), %rcx       # 0x235a
movb (%rax,%rcx), %al
movb %al, -0x80(%rbp)
movslq (%r12), %rax
leaq 0xa0f(%rip), %r14       # 0x2356
movb (%rax,%r14), %al
movb %al, -0x7f(%rbp)
movslq 0x4(%rdx), %rax
movb (%rax,%rcx), %al
movb %al, -0x7e(%rbp)
movq %r12, -0x98(%rbp)
movslq 0x4(%r12), %rax
movb (%rax,%r14), %al
movb %al, -0x7d(%rbp)
movslq (%r13), %rax
movb (%rax,%rcx), %al
movb %al, -0x7c(%rbp)
movq %rbx, -0xa0(%rbp)
movslq (%rbx), %rax
movb (%rax,%r14), %al
movb %al, -0x7b(%rbp)
movb $0x0, -0x7a(%rbp)
leaq -0x58(%rbp), %rsi
movl $0x1, %edx
movl -0x2c(%rbp), %edi
callq 0x1140
cmpl $-0x1, %eax
je 0x1e59
movq -0x48(%rbp), %rbx
movq %rbx, %rax
shlq $0x20, %rax
movabsq $-0x100000000, %r12     # imm = 0xFFFFFFFF00000000
addq %rax, %r12
movq %r12, %r13
sarq $0x20, %r13
sarq $0x1e, %r12
leaq 0x2852(%rip), %rax      # 0x4220
movl (%r12,%rax), %edi
leaq -0x80(%rbp), %rsi
movl $0x20, %edx
callq 0x1060
leaq 0x6eb(%rip), %rdi       # 0x20d2
movl %ebx, %esi
xorl %eax, %eax
callq 0x1070
leaq -0x34(%rbp), %rsi
movl $0x1, %edx
movl -0x2c(%rbp), %edi
callq 0x1140
movl $0xa, %edi
callq 0x1040
leaq 0x6ec(%rip), %rdi       # 0x20fe
movl %ebx, %esi
xorl %eax, %eax
callq 0x1070
leaq 0x2ffe(%rip), %rax      # 0x4a20
movl (%rax,%r15,4), %edx
movq -0x50(%rbp), %rdi
movq -0x98(%rbp), %rsi
callq 0x13f0
leaq 0x6dc(%rip), %rdi       # 0x2119
movl %ebx, %esi
xorl %eax, %eax
callq 0x1070
leaq 0x2ff3(%rip), %rax      # 0x4a40
movl (%rax,%r15,4), %edx
movq -0x40(%rbp), %rdi
movq -0xa0(%rbp), %rsi
callq 0x13f0
leaq 0x2798(%rip), %rdi      # 0x4200
movl $0x2, %esi
xorl %eax, %eax
callq 0x1110
leaq 0x3005(%rip), %rcx      # 0x4a80
movl %eax, (%r12,%rcx)
leaq 0x27aa(%rip), %r12      # 0x4230
movq %r15, -0x88(%rbp)
movq %r12, %r15
movq -0x48(%rbp), %r12
movl $0x1, %edi
callq 0x1180
leaq 0x2fdb(%rip), %rax      # 0x4a80
movl (%rax,%r13,4), %edi
movl $0x20, %edx
leaq -0x80(%rbp), %rbx
movq %rbx, %rsi
callq 0x1080
leaq 0x67f(%rip), %rdi       # 0x2140
movl %r12d, %esi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x1070
cmpl $0x544948, -0x80(%rbp)  # imm = 0x544948
jne 0x1bd7
leaq 0x2f76(%rip), %rdi      # 0x4a58
callq 0x1190
movslq 0x28e2(%rip), %rax      # 0x43d0
movslq (%r15,%rax,4), %rcx
movq -0x88(%rbp), %r15
movq %r13, %rbx
leaq 0x2f1d(%rip), %r13      # 0x4a20
movslq (%r13,%r15,4), %rdx
movq -0x50(%rbp), %rsi
movl %ecx, (%rsi,%rdx,4)
leaq 0x27ea(%rip), %rsi      # 0x4300
movslq (%rsi,%rax,4), %rsi
movq -0x98(%rbp), %rdi
movl %esi, (%rdi,%rdx,4)
leaq 0x82f(%rip), %rdi       # 0x235a
movb (%rcx,%rdi), %cl
movb %cl, -0x80(%rbp)
movb (%rsi,%r14), %cl
movb %cl, -0x7f(%rbp)
xorl %ecx, %ecx
movb %cl, -0x7e(%rbp)
incl %eax
movl %eax, 0x288b(%rip)      # 0x43d0
leal 0x1(%rdx), %eax
movl %eax, (%r13,%r15,4)
leaq 0x2f04(%rip), %rdi      # 0x4a58
callq 0x10e0
movq %rbx, %r13
leaq 0x26bd(%rip), %rax      # 0x4220
movl (%rax,%rbx,4), %edi
movl $0x20, %edx
leaq -0x80(%rbp), %rbx
movq %rbx, %rsi
callq 0x1060
leaq 0x5eb(%rip), %rdi       # 0x2169
movl %r12d, %esi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x1070
movl $0x1, 0x2ef7(%rip)      # 0x4a8c
xorl %eax, %eax
movb %al, -0x80(%rbp)
movl $0x1, %edx
movl -0x2c(%rbp), %edi
leaq -0x34(%rbp), %rsi
callq 0x1140
leaq 0x2e6e(%rip), %rax      # 0x4a20
movl (%rax,%r15,4), %esi
movq -0x50(%rbp), %rdi
callq 0x139b
cmpl $0x15, %eax
jg 0x1d33
leaq 0x2661(%rip), %r15      # 0x4230
jne 0x1a94
jmp 0x1c0b
movl -0x80(%rbp), %eax
movl $0x4e415453, %ecx       # imm = 0x4E415453
xorl %ecx, %eax
movzwl -0x7c(%rbp), %ecx
xorl $0x44, %ecx
orl %eax, %ecx
jne 0x1a94
movl $0x1, 0x2e92(%rip)      # 0x4a8c
leaq -0x34(%rbp), %rsi
movl $0x1, %edx
movl -0x2c(%rbp), %edi
callq 0x1140
movq %r13, -0xa8(%rbp)
leaq 0x2e27(%rip), %r13      # 0x4a40
movq -0x88(%rbp), %rax
movl (%r13,%rax,4), %esi
movq -0x40(%rbp), %r12
movq %r12, %rdi
movq %rsi, %rbx
callq 0x139b
cmpl $0x10, %eax
jg 0x1d43
movslq %ebx, %rax
movslq 0x2789(%rip), %r13      # 0x43d0
leal 0x1(%r13), %ecx
movq %rcx, -0xc0(%rbp)
shlq $0x2, %r13
movq %r13, -0xb8(%rbp)
movq -0x90(%rbp), %rcx
leaq (%rcx,%rax,4), %rax
movq %rax, -0xb0(%rbp)
incl %ebx
movq %rbx, -0x90(%rbp)
movq %r14, %r13
xorl %r14d, %r14d
leaq 0x6d5(%rip), %r15       # 0x235a
xorl %ebx, %ebx
movq -0x88(%rbp), %r12
movq -0xb8(%rbp), %rax
leaq (%rax,%r14,4), %rax
leaq 0x2590(%rip), %rcx      # 0x4230
movslq (%rcx,%rax), %rcx
movq -0xb0(%rbp), %rdx
leaq (%rdx,%r14,4), %rdx
leaq 0x28ba(%rip), %rsi      # 0x4570
movl %ecx, (%rsi,%rdx)
leaq 0x2640(%rip), %rsi      # 0x4300
movslq (%rsi,%rax), %rax
leaq 0x2bc5(%rip), %rsi      # 0x4890
movl %eax, (%rsi,%rdx)
movb (%rcx,%r15), %cl
movb %cl, -0x80(%rbp,%r14,2)
movb (%rax,%r13), %al
addq $0x2, %rbx
movb %al, -0x7f(%rbp,%r14,2)
movq -0xc0(%rbp), %rax
addl %r14d, %eax
movl %eax, 0x26dc(%rip)      # 0x43d0
movq -0x90(%rbp), %rax
leal (%rax,%r14), %esi
leaq 0x2d3a(%rip), %rax      # 0x4a40
movl %esi, (%rax,%r12,4)
movq -0x40(%rbp), %rdi
callq 0x139b
incq %r14
cmpl $0x11, %eax
jl 0x1c8e
andl $-0x2, %ebx
movq -0x48(%rbp), %r15
movq -0x40(%rbp), %r12
leaq 0x2d0f(%rip), %r13      # 0x4a40
jmp 0x1d49
movq -0x48(%rbp), %r15
leaq 0x44e(%rip), %rdi       # 0x218c
jmp 0x1e3b
xorl %ebx, %ebx
movq -0x48(%rbp), %r15
movb $0x0, -0x80(%rbp,%rbx)
movl $0xa, %edi
callq 0x1040
leaq 0x39f(%rip), %rdi       # 0x20fe
movl %r15d, %esi
xorl %eax, %eax
callq 0x1070
movq -0x88(%rbp), %rbx
leaq 0x2ca9(%rip), %rax      # 0x4a20
movl (%rax,%rbx,4), %edx
movq -0x50(%rbp), %r14
movq %r14, %rdi
movq -0x98(%rbp), %rsi
callq 0x13f0
leaq 0x428(%rip), %rdi       # 0x21bc
movl %r15d, %esi
xorl %eax, %eax
callq 0x1070
movl (%r13,%rbx,4), %edx
movq %r12, %rdi
movq -0xa0(%rbp), %rsi
callq 0x13f0
leaq -0x58(%rbp), %rsi
movl $0x1, %edx
movl -0x2c(%rbp), %edi
callq 0x1140
cmpl $-0x1, %eax
je 0x1e5e
movq -0xa8(%rbp), %rax
leaq 0x2446(%rip), %rcx      # 0x4220
movl (%rcx,%rax,4), %edi
leaq -0x80(%rbp), %rsi
movl $0x20, %edx
callq 0x1060
leaq 0x2c2e(%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 0x1e1b
leaq 0x3ca(%rip), %rdi       # 0x21e3
jmp 0x1e3b
cmpl %eax, %r14d
jne 0x1e29
leaq 0x3e7(%rip), %rdi       # 0x220e
jmp 0x1e3b
leaq 0x421(%rip), %rax       # 0x2251
leaq 0x45d(%rip), %rdi       # 0x2294
cmovlq %rax, %rdi
movl %r15d, %esi
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