void GameManager::NET_PlayGameFlow() { Network network; PacketType type; ErrorType error; try { Network::Initialize(); } catch (Network::Exception) { puts("초기화 도중 문제가 발생했습니다."); return; } try { network.Connect("10.73.42.117", 9000); } catch (Network::Exception ex) { switch (ex) { case Network::NETWORK_ERROR: puts("서버와 연결에 실패했습니다."); break; case Network::PARAMETER_ERROR: puts("함수의 인수가 잘못되었습니다."); break; } return; } puts("접속 성공!"); try { const wchar_t name[MAX_NAME_LEN] = L"지면 F"; const int studentID = 141055; error = network.SubmitName(name, studentID); if (error == ET_DUPLICATED_NAME) { puts("이미 존재하는 이름입니다."); return; } Network::GameStartData gameStartData; puts("게임 시작 대기중"); network.WaitForStart(&gameStartData); wprintf_s(L"매칭되었습니다. 상대방 이름: %s, 학번: %d\n", gameStartData.oppositionName, gameStartData.oppositionStudentID); bool allOver = false; while (!allOver) //10판 종료 { ShipData shipData; Network::Initialize(); char mapData[MAP_SIZE]; while (true) { ReadyToFight(m_Player1); ReadyToFight(m_Player2); m_GameRenderer->RenderPages(GAMEPLAY, NET_PLAY); for (int i = 0; i < DEFAULT_SHIP_COUNT; ++i) { Position netPosition; if (i != 4) netPosition = ConvertPosionForNET((ShipType)i, m_ShipPositions[i]); else if (i == 4) netPosition = ConvertPosionForNET((ShipType)(i - 1), m_ShipPositions[i]); shipData.SetShip((ShipData::ShipType)(i + 1), Coord(netPosition.m_X, netPosition.m_Y), netPosition.m_direction == 0 ? ShipData::DIR_VERTICAL : ShipData::DIR_HORIZONTAL); } shipData.ToMapData(mapData); error = network.SubmitMap(mapData); if (error == ET_INVALID_MAP) puts("유효하지 않은 맵 데이터입니다."); else break; } bool gameOver = false; while (!gameOver) { error = network.GetPacketType(&type); switch (type) { case PKT_SC_ERROR: if (error == ET_OPPOSITION_DISCONNECTED) puts("상대방의 접속이 끊어졌습니다."); else puts("알 수 없는 에러입니다."); return; case PKT_SC_MY_TURN: /* 공격 위치 전송 x, y는 0~7 사이의 정수이다.*/ { Coordinate netShot; bool isAttacked; while (true) { do { netShot = m_Player1->RandomAttack(); //Make AI Attack T-T //netShot = m_GameInterface->AttackInterface(FIRST_MAP_GOTOX, FIRST_MAP_GOTOY); //Manual Mode isAttacked = m_Player2->CheckAttacked(netShot); } while (isAttacked); Coord myShot(netShot.m_X, netShot.m_Y); error = network.SubmitAttack(myShot); if (error == ET_INVALID_ATTACK) printf_s("유효하지 않은 공격"); else break; } break; } case PKT_SC_ATTACK_RESULT: { Network::AttackResultData attackResult = network.GetAttackResult(); Coordinate shot; shot.m_X = attackResult.pos.mX; shot.m_Y = attackResult.pos.mY; HitResult shotResult = (HitResult)attackResult.attackResult; if (attackResult.isMine) //내 에너미 맵에 내가 공격한 결과를 반영 마크 { m_GameRenderer->PrintResult(shotResult); m_GameRenderer->PrintTurn(++m_Turn, DEFAULT_MAP_SIZE); m_Player1->MarkOnEnemyMap(shot, shotResult); m_Player2->MarkOnMyMap(shot, shotResult); m_Player1->RenderUpdateEnemyMapStatus(FIRST_MAP_GOTOX, FIRST_MAP_GOTOY); } else //내가 어택당하는 함수 { m_Player1->MarkOnMyMap(shot, shotResult); m_Player1->RenderUpdateMyMapStatus((m_MapSize + 3) * 4 + 30, FIRST_MAP_GOTOY); } break; } case PKT_SC_GAME_OVER: { Network::GameResultData gameResult = network.GetGameResult(); ResetGame(); if (gameResult.isWinner) puts("승리!!!"); else puts("패배..."); printf_s("턴 수: %d\n", gameResult.turns); gameOver = true; break; } default: throw Network::UNEXPECTED_PACKET; break; } } network.GetPacketType(&type); if (type == PKT_SC_NEXT_GAME) { puts("다음 게임을 준비해주세요."); } else if (type == PKT_SC_ALL_OVER) { Network::FinalResultData finalResult = network.GetFinalResult(); allOver = true; } else throw Network::UNEXPECTED_PACKET; } } catch (Network::Exception ex) { switch (ex) { case Network::NETWORK_ERROR: puts("네트워크에 문제가 발생했습니다."); break; case Network::SERVER_CLOSED: puts("서버와의 연결이 끊어졌습니다."); break; case Network::PARAMETER_ERROR: puts("함수의 인수가 잘못되었습니다."); break; case Network::UNEXPECTED_PACKET: puts("서버에서 잘못된 정보가 전송되었습니다."); break; default: break; } } network.Disconnect(); m_GameStatus = WIN; }
// ShipData 구조체를 사용해서 맵 데이터 생성하는 방법 void MakeMapData2(char* const mapData) { ShipData shipData; char map[MAP_SIZE] = { 0, }; int size, sx, sy, dir, listIdx = 0; bool placeable; Coord posArr[MAX_SHIP_LEN]; // ShipData에 넣을 배의 위치 배열 for (int type = MD_NONE + 1; type < MD_END; ++type) { while (true) { size = ShipData::SHIP_LEN[type]; placeable = true; dir = rand() % 2; if (dir == 0) // hori { sx = rand() % (MAP_WIDTH - size); sy = rand() % MAP_HEIGHT; } else // vert { sx = rand() % MAP_WIDTH; sy = rand() % (MAP_HEIGHT - size); } for (int i = 0; i < size && placeable; ++i) { if (dir == 0 && map[sx + i + sy * MAP_WIDTH]) placeable = false; else if (dir == 1 && map[sx + (sy + i) * MAP_WIDTH]) placeable = false; } if (placeable) break; } // 1.2 배의 좌표 배열을 가져와서... Coord* shipPosArr = shipData.GetShipCoordArray((ShipType)type); for (int i = 0; i < size && placeable; ++i) { int x, y; Coord coord; if (dir == 0) { x = sx + i; y = sy; } else { x = sx; y = sy + i; } map[x + y * MAP_WIDTH] = type; coord = Coord(x, y); // 1. 배의 좌표를 하나씩 넣는 방법 // 1.1. 함수 사용 shipData.SetShipCoord((ShipType)type, i, coord); // 1.2. 배열을 가져와서 넣기 // shipPosArr[i] = coord; // 2. Coord 배열을 만들어서... // posArr[i] = coord; } // 2. 배의 좌표를 배열로 한 번에 넣는 방법 // shipData.SetShip((ShipType)type, posArr); // 3. 배의 시작지점과 방향만 넣는 방법 // shipData.SetShip((ShipType)type, Coord(sx, sy), dir==0 ? DIR_HORIZONTAL:DIR_VERTICAL); } // 배의 배치를 맵 데이터로 변환 shipData.ToMapData(mapData); }