Implemented two-player mode and GUI.
This commit is contained in:
parent
8ea7d8a840
commit
bfe8c9f598
@ -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,6 +254,7 @@ 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(playingAgainstAI){
|
||||||
if(aiThinkTime>0){
|
if(aiThinkTime>0){
|
||||||
aiThinkTime-=fElapsedTime;
|
aiThinkTime-=fElapsedTime;
|
||||||
|
|
||||||
@ -237,12 +264,26 @@ public:
|
|||||||
chosenIndex=rand()%9;
|
chosenIndex=rand()%9;
|
||||||
}
|
}
|
||||||
gamePieces[chosenIndex].piece=opponentSide;
|
gamePieces[chosenIndex].piece=opponentSide;
|
||||||
|
player1Turn=!player1Turn;
|
||||||
AnalyzeBoard();
|
AnalyzeBoard();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string displayText=" The AI \nis thinking...";
|
std::string displayText=" The AI \nis thinking...";
|
||||||
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});
|
||||||
|
}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){
|
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){
|
||||||
|
if(!playingAgainstAI){
|
||||||
|
if(player1Turn){
|
||||||
gamePieces[index].piece=playerSide;
|
gamePieces[index].piece=playerSide;
|
||||||
|
}else{
|
||||||
|
gamePieces[index].piece=opponentSide;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
gamePieces[index].piece=playerSide;
|
||||||
|
}
|
||||||
dragging=false;
|
dragging=false;
|
||||||
|
if(playingAgainstAI){
|
||||||
aiThinkTime=rand()%3+1;
|
aiThinkTime=rand()%3+1;
|
||||||
|
}
|
||||||
|
player1Turn=!player1Turn;
|
||||||
AnalyzeBoard();
|
AnalyzeBoard();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -281,6 +333,7 @@ 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(playingAgainstAI||player1Turn){
|
||||||
if(dragging){
|
if(dragging){
|
||||||
pieceCount++;
|
pieceCount++;
|
||||||
dragging=false;
|
dragging=false;
|
||||||
@ -289,6 +342,17 @@ public:
|
|||||||
dragging=true;
|
dragging=true;
|
||||||
pieceCount--;
|
pieceCount--;
|
||||||
}
|
}
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
if(dragging){
|
||||||
|
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){
|
||||||
|
if(playingAgainstAI||player1Turn){
|
||||||
DrawRotatedDecal(GetMousePos(),pieceImg,0,pieceImg->sprite->Size()/2);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1170
TicTacToe-Game/olcPGEX_QuickGUI.h
Normal file
1170
TicTacToe-Game/olcPGEX_QuickGUI.h
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user