Implemented two-player mode and GUI.

master
sigonasr2 1 year ago
parent 8ea7d8a840
commit bfe8c9f598
  1. 5
      TicTacToe-Game/TicTacToe-Game.vcxproj
  2. 3
      TicTacToe-Game/TicTacToe-Game.vcxproj.filters
  3. 83
      TicTacToe-Game/TicTacToe.cpp
  4. 1170
      TicTacToe-Game/olcPGEX_QuickGUI.h

@ -76,6 +76,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -90,6 +91,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -104,6 +106,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -118,6 +121,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -127,6 +131,7 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="olcPGEX_QuickGUI.h" />
<ClInclude Include="olcPixelGameEngine.h" />
</ItemGroup>
<ItemGroup>

@ -18,6 +18,9 @@
<ClInclude Include="olcPixelGameEngine.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="olcPGEX_QuickGUI.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="TicTacToe.cpp">

@ -1,5 +1,8 @@
#define OLC_PGE_APPLICATION
#include "olcPixelGameEngine.h"
#define OLC_PGEX_QUICKGUI
#include "olcPGEX_QuickGUI.h"
using namespace olc;
@ -45,7 +48,7 @@ public:
Decal*crossImg;
Decal*gridImg;
int pieceCount=5;
int pieceCount=5,pieceCount2=5;
PieceType playerSide=CIRCLE;
PieceType opponentSide=CROSS;
@ -56,11 +59,16 @@ public:
float aiThinkTime=0;
bool playingAgainstAI=true;
GameState state=PLAYING;
GameState state=MENU;
Winner outcome=TIE;
vf2d winLine1,winLine2;
bool player1Turn=true;
QuickGUI::Button*aiButton;
QuickGUI::Button*twoPlayerButton;
void SetOutcome(int score){
if(score==3){
outcome=PLAYER_1;
@ -169,6 +177,8 @@ public:
}
}
QuickGUI::Manager gui;
public:
bool OnUserCreate() override
{
@ -183,6 +193,9 @@ public:
circleImg=new Decal(new Sprite("circle.png"));
crossImg=new Decal(new Sprite("cross.png"));
gridImg=new Decal(new Sprite("grid.png"));
aiButton=new QuickGUI::Button(gui,"Play Against AI",{8,64},{ScreenWidth()-16.f,12});
twoPlayerButton=new QuickGUI::Button(gui,"Play As 2 Players",{8,80},{ScreenWidth()-16.f,12});
return true;
}
@ -192,17 +205,30 @@ public:
switch(state){
case MENU:{
DrawStringDecal({0,0},"This is the menu.");
gui.Update(this);
gui.Draw(this);
if(aiButton->bPressed){
state=PLAYING;
playingAgainstAI=true;
}
if(twoPlayerButton->bPressed){
state=PLAYING;
playingAgainstAI=false;
}
}break;
case PLAYING:
case GAMEOVER:{
vf2d gridOffset={16,16};
Decal*pieceImg;
Decal*opponentPieceImg;
if(playerSide==CIRCLE){
pieceImg=circleImg;
opponentPieceImg=crossImg;
}else{
pieceImg=crossImg;
opponentPieceImg=circleImg;
}
if(state==GAMEOVER){
@ -228,6 +254,7 @@ public:
DrawStringDecal(vf2d{ScreenWidth()/2.f,4}-gameOverTextSize/2,gameOverText,BLACK,{0.5,0.5});
DrawStringDecal(vf2d{ScreenWidth()/2.f,12}-winnerTextSize/2,winnerText,BLACK,{0.5,0.5});
}else{
if(playingAgainstAI){
if(aiThinkTime>0){
aiThinkTime-=fElapsedTime;
@ -237,12 +264,26 @@ public:
chosenIndex=rand()%9;
}
gamePieces[chosenIndex].piece=opponentSide;
player1Turn=!player1Turn;
AnalyzeBoard();
}
std::string displayText=" The AI \nis thinking...";
vf2d textSize=vf2d{GetTextSize(displayText)}*0.5;
DrawStringDecal(vf2d{ScreenWidth()/2.f,8}-textSize/2,displayText,BLACK,{0.5,0.5});
}else{
std::string displayText="Player's Turn";
vf2d textSize=vf2d{GetTextSize(displayText)}*0.5;
DrawStringDecal(vf2d{ScreenWidth()/2.f,8}-textSize/2,displayText,BLACK,{0.5,0.5});
}
}
else{
std::string displayText="Player 1's Turn";
if(!player1Turn){
displayText="Player 2's Turn";
}
vf2d textSize=vf2d{GetTextSize(displayText)}*0.5;
DrawStringDecal(vf2d{ScreenWidth()/2.f,8}-textSize/2,displayText,BLACK,{0.5,0.5});
}
}
@ -255,11 +296,22 @@ public:
if(GetMouseX()>=upperLeftCorner.x&&GetMouseX()<lowerRightCorner.x&&GetMouseY()>=upperLeftCorner.y&&GetMouseY()<lowerRightCorner.y){
FillRectDecal(gridOffset+vf2d{float(x),float(y)}*32,{32,32},{0,0,0,64});
if(dragging&&GetMouse(Mouse::LEFT).bPressed&&aiThinkTime<=0){
if(dragging&&GetMouse(Mouse::LEFT).bPressed&&aiThinkTime<=0&&state!=GAMEOVER){
if(gamePieces[index].piece==BLANK){
if(!playingAgainstAI){
if(player1Turn){
gamePieces[index].piece=playerSide;
}else{
gamePieces[index].piece=opponentSide;
}
}else{
gamePieces[index].piece=playerSide;
}
dragging=false;
if(playingAgainstAI){
aiThinkTime=rand()%3+1;
}
player1Turn=!player1Turn;
AnalyzeBoard();
}
}
@ -281,6 +333,7 @@ public:
FillRectDecal({0,120},{float(ScreenWidth()),40},{0,0,0,64});
if(GetMouse(Mouse::LEFT).bPressed){
if(playingAgainstAI||player1Turn){
if(dragging){
pieceCount++;
dragging=false;
@ -289,6 +342,17 @@ public:
dragging=true;
pieceCount--;
}
}else
{
if(dragging){
pieceCount2++;
dragging=false;
}else
if(pieceCount2>0){
dragging=true;
pieceCount2--;
}
}
}
}
@ -299,12 +363,21 @@ public:
DrawDecal(gridOffset,gridImg);
if(dragging){
if(playingAgainstAI||player1Turn){
DrawRotatedDecal(GetMousePos(),pieceImg,0,pieceImg->sprite->Size()/2);
}else{
DrawRotatedDecal(GetMousePos(),opponentPieceImg,0,opponentPieceImg->sprite->Size()/2);
}
}
for(int i=0;i<pieceCount;i++){
DrawDecal(vf2d{4.f+i*8,128},pieceImg);
}
if(!playingAgainstAI){
for(int i=0;i<pieceCount2;i++){
DrawDecal(vf2d{ScreenWidth()-4.f-32-i*8,128},opponentPieceImg);
}
}
}break;
}

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save