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. 121
      TicTacToe-Game/TicTacToe.cpp
  4. 1170
      TicTacToe-Game/olcPGEX_QuickGUI.h

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

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

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

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