// File: /workspace/github_c_makefile_star2_O2/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 $0x88, %rsp
movq %rdi, %r15
movl %r15d, %eax
movq %rax, -0x48(%rbp)
leal 0xeac5(%rax), %ebx
movw $0x1000, %ax            # imm = 0x1000
movw %ax, -0x4c(%rbp)
movl $0xffff0000, -0x50(%rbp) # imm = 0xFFFF0000
movw %ax, -0x30(%rbp)
movl $0x10000, -0x34(%rbp)   # imm = 0x10000
pushq $0x1
popq %rsi
movl %ebx, %edi
movl $0x7b6, %edx            # imm = 0x7B6
callq 0x1030
cmpl $-0x1, %eax
jne 0x1766
movl %ebx, %edi
xorl %esi, %esi
xorl %edx, %edx
callq 0x1030
cmpl $-0x1, %eax
je 0x1da7
movl %eax, %esi
shlq $0x20, %r15
movq %r15, -0x98(%rbp)
movslq -0x48(%rbp), %r14
imulq $0x50, %r14, %r13
leaq 0x2c5e(%rip), %r15      # 0x43e0
leaq (%r15,%r13), %rax
movq %rax, -0x40(%rbp)
leaq 0x2ddf(%rip), %rax      # 0x4570
addq %r13, %rax
movq %rax, -0x60(%rbp)
leaq 0x2f61(%rip), %r12      # 0x4700
leaq (%r12,%r13), %rax
movq %rax, -0x58(%rbp)
leaq 0x30e2(%rip), %rax      # 0x4890
addq %r13, %rax
movq %rax, -0x88(%rbp)
xorl %ebx, %ebx
pushq $0x10
popq %rdx
pushq $0x1
popq %rcx
movl %esi, -0x2c(%rbp)
movl %esi, %edi
xorl %esi, %esi
xorl %eax, %eax
callq 0x1140
leaq 0x324b(%rip), %rax      # 0x4a20
andl $0x0, (%rax,%r14,4)
leaq 0x325f(%rip), %rax      # 0x4a40
andl $0x0, (%rax,%r14,4)
leaq 0x326b(%rip), %rdi      # 0x4a58
callq 0x11a0
movslq 0x2bd7(%rip), %rax      # 0x43d0
movq %r14, -0xa0(%rbp)
leaq 0x3219(%rip), %rcx      # 0x4a20
movslq (%rcx,%r14,4), %rdi
movq %rcx, %r14
movl %edi, %edx
movq %rax, %rcx
shlq $0x20, %rcx
movq %rax, %rsi
shlq $0x2, %rsi
movq %r13, -0x90(%rbp)
leaq (,%rdi,4), %rdi
addq %r13, %rdi
movabsq $0x100000000, %r8       # imm = 0x100000000
cmpl $0x2, %ebx
je 0x186d
leaq (%rsi,%rbx,4), %r9
leaq 0x29e6(%rip), %r10      # 0x4230
movl (%r10,%r9), %r10d
leaq (%rdi,%rbx,4), %r11
movl %r10d, (%r15,%r11)
leaq 0x2aa3(%rip), %r10      # 0x4300
movl (%r10,%r9), %r9d
movl %r9d, (%r12,%r11)
addq %r8, %rcx
incq %rbx
jmp 0x183a
addl %ebx, %edx
movq -0xa0(%rbp), %r15
movl %edx, (%r14,%r15,4)
sarq $0x1e, %rcx
leaq 0x29ab(%rip), %rdx      # 0x4230
movl (%rcx,%rdx), %edx
leaq 0x31b1(%rip), %rdi      # 0x4a40
movslq (%rdi,%r15,4), %rsi
movq -0x60(%rbp), %r14
movl %edx, (%r14,%rsi,4)
leaq 0x2a5e(%rip), %rdx      # 0x4300
movl (%rcx,%rdx), %ecx
movq -0x88(%rbp), %r12
movl %ecx, (%r12,%rsi,4)
leal 0x1(%rax,%rbx), %eax
movl %eax, 0x2b16(%rip)      # 0x43d0
leal 0x1(%rsi), %eax
movl %eax, (%rdi,%r15,4)
leaq 0x3190(%rip), %rdi      # 0x4a58
callq 0x10e0
movq -0x40(%rbp), %rdi
movslq (%rdi), %rax
leaq 0xa7f(%rip), %rcx       # 0x235a
movb (%rax,%rcx), %al
movb %al, -0x80(%rbp)
movq -0x58(%rbp), %rsi
movslq (%rsi), %rax
leaq 0xa67(%rip), %rdx       # 0x2356
movb (%rax,%rdx), %al
movb %al, -0x7f(%rbp)
movslq 0x4(%rdi), %rax
movb (%rax,%rcx), %al
movb %al, -0x7e(%rbp)
movslq 0x4(%rsi), %rax
movb (%rax,%rdx), %al
movb %al, -0x7d(%rbp)
movslq (%r14), %rax
movb (%rax,%rcx), %al
movb %al, -0x7c(%rbp)
movslq (%r12), %rax
movb (%rax,%rdx), %al
movb %al, -0x7b(%rbp)
movb $0x0, -0x7a(%rbp)
leaq -0x50(%rbp), %rsi
pushq $0x1
popq %rdx
movl -0x2c(%rbp), %r13d
movl %r13d, %edi
callq 0x1150
cmpl $-0x1, %eax
je 0x1d93
movabsq $-0x100000000, %rax     # imm = 0xFFFFFFFF00000000
movq -0x98(%rbp), %r12
addq %rax, %r12
movq %r12, %rax
sarq $0x20, %rax
movq %rax, -0xa8(%rbp)
sarq $0x1e, %r12
leaq 0x28b7(%rip), %rax      # 0x4220
movl (%r12,%rax), %edi
leaq -0x80(%rbp), %rbx
pushq $0x20
popq %rdx
movq %rbx, %rsi
callq 0x1060
leaq 0x74f(%rip), %rdi       # 0x20d2
movq -0x48(%rbp), %r14
movl %r14d, %esi
xorl %eax, %eax
callq 0x1070
leaq -0x34(%rbp), %rsi
pushq $0x1
popq %rdx
movl %r13d, %edi
pushq $0x20
popq %r13
callq 0x1150
pushq $0xa
popq %rdi
callq 0x1040
leaq 0x74b(%rip), %rdi       # 0x20fe
movl %r14d, %esi
xorl %eax, %eax
callq 0x1070
leaq 0x305c(%rip), %rax      # 0x4a20
movl (%rax,%r15,4), %edx
movq -0x40(%rbp), %rdi
movq -0x58(%rbp), %rsi
callq 0x137c
leaq 0x73d(%rip), %rdi       # 0x2119
movl %r14d, %esi
xorl %eax, %eax
callq 0x1070
leaq 0x3053(%rip), %r14      # 0x4a40
movl (%r14,%r15,4), %edx
movq -0x60(%rbp), %rdi
movq -0x88(%rbp), %rsi
callq 0x137c
leaq 0x27f8(%rip), %rdi      # 0x4200
pushq $0x2
popq %rsi
xorl %eax, %eax
callq 0x1120
leaq 0x3067(%rip), %rcx      # 0x4a80
movl %eax, (%r12,%rcx)
movq -0xa8(%rbp), %r12
pushq $0x1
popq %rdi
callq 0x1190
leaq 0x304d(%rip), %rax      # 0x4a80
movl (%rax,%r12,4), %edi
movq %rbx, %rsi
movq %r13, %rdx
callq 0x1080
leaq 0x6f7(%rip), %rdi       # 0x2140
movq -0x48(%rbp), %rsi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x1070
cmpl $0x544948, -0x80(%rbp)  # imm = 0x544948
jne 0x1b68
leaq 0x2fed(%rip), %rdi      # 0x4a58
callq 0x11a0
movslq 0x2959(%rip), %rax      # 0x43d0
leaq 0x27b2(%rip), %rcx      # 0x4230
movslq (%rcx,%rax,4), %rcx
movq %r12, %r14
leaq 0x2f94(%rip), %r12      # 0x4a20
movslq (%r12,%r15,4), %rdx
movq -0x40(%rbp), %rsi
movl %ecx, (%rsi,%rdx,4)
leaq 0x2862(%rip), %rsi      # 0x4300
movslq (%rsi,%rax,4), %rsi
movq -0x58(%rbp), %rdi
movl %esi, (%rdi,%rdx,4)
leaq 0x8aa(%rip), %rdi       # 0x235a
movb (%rcx,%rdi), %cl
movb %cl, -0x80(%rbp)
leaq 0x899(%rip), %rcx       # 0x2356
movb (%rsi,%rcx), %cl
movb %cl, -0x7f(%rbp)
xorl %ecx, %ecx
movb %cl, -0x7e(%rbp)
incl %eax
movl %eax, 0x2900(%rip)      # 0x43d0
leal 0x1(%rdx), %eax
movl %eax, (%r12,%r15,4)
leaq 0x2f7a(%rip), %rdi      # 0x4a58
callq 0x10e0
movq %r14, %r12
leaq 0x2733(%rip), %rax      # 0x4220
movl (%rax,%r14,4), %edi
movq %rbx, %rsi
movq %r13, %rdx
callq 0x1060
leaq 0x666(%rip), %rdi       # 0x2169
movq -0x48(%rbp), %rsi
movq %rsi, %r14
movq %rbx, %r13
movq %rbx, %rdx
xorl %eax, %eax
callq 0x1070
movl $0x1, 0x2f6b(%rip)      # 0x4a8c
xorl %eax, %eax
movb %al, -0x80(%rbp)
movl -0x2c(%rbp), %edi
leaq -0x34(%rbp), %rsi
pushq $0x1
popq %rdx
callq 0x1150
leaq 0x2ee4(%rip), %rax      # 0x4a20
movl (%rax,%r15,4), %esi
movq -0x40(%rbp), %rdi
callq 0x1331
cmpl $0x15, %eax
jg 0x1d4d
leaq 0x2ee7(%rip), %r14      # 0x4a40
movq %r13, %rbx
pushq $0x20
popq %r13
jne 0x1a24
jmp 0x1b9b
movq %rbx, %rdi
leaq 0x644(%rip), %rsi       # 0x21b6
pushq $0x6
popq %rdx
callq 0x1100
testl %eax, %eax
jne 0x1a24
movl $0x1, 0x2f00(%rip)      # 0x4a8c
leaq -0x34(%rbp), %rsi
pushq $0x1
popq %rdx
movl -0x2c(%rbp), %edi
callq 0x1150
movl (%r14,%r15,4), %eax
movslq 0x282a(%rip), %r14      # 0x43d0
movq %rax, %r15
movslq %eax, %rcx
movq -0x90(%rbp), %rax
movq %rcx, -0x98(%rbp)
leaq (%rax,%rcx,4), %rax
movq %rax, -0x90(%rbp)
leal 0x1(%r14), %r12d
shlq $0x2, %r14
xorl %ebx, %ebx
xorl %r13d, %r13d
leal (%r15,%rbx), %esi
movq -0x60(%rbp), %rdi
callq 0x1331
cmpl $0x10, %eax
jg 0x1c6f
leaq (%r14,%rbx,4), %rax
leaq 0x263d(%rip), %rcx      # 0x4230
movslq (%rcx,%rax), %rcx
movq -0x90(%rbp), %rdx
leaq (%rdx,%rbx,4), %rdx
leaq 0x2967(%rip), %rsi      # 0x4570
movl %ecx, (%rsi,%rdx)
leaq 0x26ed(%rip), %rsi      # 0x4300
movslq (%rsi,%rax), %rax
leaq 0x2c72(%rip), %rsi      # 0x4890
movl %eax, (%rsi,%rdx)
leal (%r12,%rbx), %edx
movl %edx, 0x27a5(%rip)      # 0x43d0
movq -0x98(%rbp), %rdx
leal 0x1(%rdx,%rbx), %edx
movq -0xa0(%rbp), %rsi
leaq 0x2dfc(%rip), %rdi      # 0x4a40
movl %edx, (%rdi,%rsi,4)
leaq 0x70c(%rip), %rdx       # 0x235a
movb (%rcx,%rdx), %cl
movb %cl, -0x80(%rbp,%rbx,2)
leaq 0x6fa(%rip), %rcx       # 0x2356
movb (%rax,%rcx), %al
movb %al, -0x7f(%rbp,%rbx,2)
addq $0x2, %r13
incq %rbx
jmp 0x1bd2
andl $-0x2, %r13d
movb $0x0, -0x80(%rbp,%r13)
pushq $0xa
popq %rdi
callq 0x1040
leaq 0x476(%rip), %rdi       # 0x20fe
movq -0x48(%rbp), %r14
movl %r14d, %esi
xorl %eax, %eax
callq 0x1070
movq -0xa0(%rbp), %r15
leaq 0x2d7c(%rip), %rax      # 0x4a20
movl (%rax,%r15,4), %edx
movq -0x40(%rbp), %rbx
movq %rbx, %rdi
movq -0x58(%rbp), %rsi
callq 0x137c
leaq 0x4fd(%rip), %rdi       # 0x21bc
movl %r14d, %esi
xorl %eax, %eax
callq 0x1070
leaq 0x2d70(%rip), %r13      # 0x4a40
movl (%r13,%r15,4), %edx
movq -0x60(%rbp), %r12
movq %r12, %rdi
movq -0x88(%rbp), %rsi
callq 0x137c
leaq -0x50(%rbp), %rsi
pushq $0x1
popq %rdx
movl -0x2c(%rbp), %edi
callq 0x1150
cmpl $-0x1, %eax
je 0x1d93
movq -0xa8(%rbp), %rax
leaq 0x2512(%rip), %rcx      # 0x4220
movl (%rcx,%rax,4), %edi
pushq $0x20
popq %rdx
leaq -0x80(%rbp), %rsi
callq 0x1060
leaq 0x2cfc(%rip), %rax      # 0x4a20
movl (%rax,%r15,4), %esi
movq %rbx, %rdi
callq 0x1331
movl %eax, %ebx
movl (%r13,%r15,4), %esi
movq %r12, %rdi
callq 0x1331
cmpl $0x15, %eax
jle 0x1d56
leaq 0x498(%rip), %rdi       # 0x21e3
jmp 0x1d75
leaq 0x438(%rip), %rdi       # 0x218c
jmp 0x1d75
cmpl %eax, %ebx
jne 0x1d63
leaq 0x4ad(%rip), %rdi       # 0x220e
jmp 0x1d75
leaq 0x4e7(%rip), %rax       # 0x2251
leaq 0x523(%rip), %rdi       # 0x2294
cmovlq %rax, %rdi
movl %r14d, %esi
xorl %eax, %eax
callq 0x1070
xorl %eax, %eax
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x31e(%rip), %rdi       # 0x20b8
callq 0x1130
pushq $0x1
popq %rdi
callq 0x1170
leaq 0x2bb(%rip), %rdi       # 0x2069
jmp 0x1d9a