parent
065f105171
commit
8ea7d8a840
@ -0,0 +1,138 @@ |
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
<ItemGroup Label="ProjectConfigurations"> |
||||
<ProjectConfiguration Include="Debug|Win32"> |
||||
<Configuration>Debug</Configuration> |
||||
<Platform>Win32</Platform> |
||||
</ProjectConfiguration> |
||||
<ProjectConfiguration Include="Release|Win32"> |
||||
<Configuration>Release</Configuration> |
||||
<Platform>Win32</Platform> |
||||
</ProjectConfiguration> |
||||
<ProjectConfiguration Include="Debug|x64"> |
||||
<Configuration>Debug</Configuration> |
||||
<Platform>x64</Platform> |
||||
</ProjectConfiguration> |
||||
<ProjectConfiguration Include="Release|x64"> |
||||
<Configuration>Release</Configuration> |
||||
<Platform>x64</Platform> |
||||
</ProjectConfiguration> |
||||
</ItemGroup> |
||||
<PropertyGroup Label="Globals"> |
||||
<VCProjectVersion>16.0</VCProjectVersion> |
||||
<Keyword>Win32Proj</Keyword> |
||||
<ProjectGuid>{a0ef2eb9-11a1-4f5a-b617-12635b8561db}</ProjectGuid> |
||||
<RootNamespace>TicTacToeGame</RootNamespace> |
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> |
||||
</PropertyGroup> |
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> |
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> |
||||
<ConfigurationType>Application</ConfigurationType> |
||||
<UseDebugLibraries>true</UseDebugLibraries> |
||||
<PlatformToolset>v143</PlatformToolset> |
||||
<CharacterSet>Unicode</CharacterSet> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> |
||||
<ConfigurationType>Application</ConfigurationType> |
||||
<UseDebugLibraries>false</UseDebugLibraries> |
||||
<PlatformToolset>v143</PlatformToolset> |
||||
<WholeProgramOptimization>true</WholeProgramOptimization> |
||||
<CharacterSet>Unicode</CharacterSet> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> |
||||
<ConfigurationType>Application</ConfigurationType> |
||||
<UseDebugLibraries>true</UseDebugLibraries> |
||||
<PlatformToolset>v143</PlatformToolset> |
||||
<CharacterSet>Unicode</CharacterSet> |
||||
</PropertyGroup> |
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> |
||||
<ConfigurationType>Application</ConfigurationType> |
||||
<UseDebugLibraries>false</UseDebugLibraries> |
||||
<PlatformToolset>v143</PlatformToolset> |
||||
<WholeProgramOptimization>true</WholeProgramOptimization> |
||||
<CharacterSet>Unicode</CharacterSet> |
||||
</PropertyGroup> |
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> |
||||
<ImportGroup Label="ExtensionSettings"> |
||||
</ImportGroup> |
||||
<ImportGroup Label="Shared"> |
||||
</ImportGroup> |
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> |
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> |
||||
</ImportGroup> |
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> |
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> |
||||
</ImportGroup> |
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> |
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> |
||||
</ImportGroup> |
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> |
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> |
||||
</ImportGroup> |
||||
<PropertyGroup Label="UserMacros" /> |
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> |
||||
<ClCompile> |
||||
<WarningLevel>Level3</WarningLevel> |
||||
<SDLCheck>true</SDLCheck> |
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
<ConformanceMode>true</ConformanceMode> |
||||
</ClCompile> |
||||
<Link> |
||||
<SubSystem>Console</SubSystem> |
||||
<GenerateDebugInformation>true</GenerateDebugInformation> |
||||
</Link> |
||||
</ItemDefinitionGroup> |
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> |
||||
<ClCompile> |
||||
<WarningLevel>Level3</WarningLevel> |
||||
<FunctionLevelLinking>true</FunctionLevelLinking> |
||||
<IntrinsicFunctions>true</IntrinsicFunctions> |
||||
<SDLCheck>true</SDLCheck> |
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
<ConformanceMode>true</ConformanceMode> |
||||
</ClCompile> |
||||
<Link> |
||||
<SubSystem>Console</SubSystem> |
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding> |
||||
<OptimizeReferences>true</OptimizeReferences> |
||||
<GenerateDebugInformation>true</GenerateDebugInformation> |
||||
</Link> |
||||
</ItemDefinitionGroup> |
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> |
||||
<ClCompile> |
||||
<WarningLevel>Level3</WarningLevel> |
||||
<SDLCheck>true</SDLCheck> |
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
<ConformanceMode>true</ConformanceMode> |
||||
</ClCompile> |
||||
<Link> |
||||
<SubSystem>Console</SubSystem> |
||||
<GenerateDebugInformation>true</GenerateDebugInformation> |
||||
</Link> |
||||
</ItemDefinitionGroup> |
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> |
||||
<ClCompile> |
||||
<WarningLevel>Level3</WarningLevel> |
||||
<FunctionLevelLinking>true</FunctionLevelLinking> |
||||
<IntrinsicFunctions>true</IntrinsicFunctions> |
||||
<SDLCheck>true</SDLCheck> |
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> |
||||
<ConformanceMode>true</ConformanceMode> |
||||
</ClCompile> |
||||
<Link> |
||||
<SubSystem>Console</SubSystem> |
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding> |
||||
<OptimizeReferences>true</OptimizeReferences> |
||||
<GenerateDebugInformation>true</GenerateDebugInformation> |
||||
</Link> |
||||
</ItemDefinitionGroup> |
||||
<ItemGroup> |
||||
<ClInclude Include="olcPixelGameEngine.h" /> |
||||
</ItemGroup> |
||||
<ItemGroup> |
||||
<ClCompile Include="TicTacToe.cpp" /> |
||||
</ItemGroup> |
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> |
||||
<ImportGroup Label="ExtensionTargets"> |
||||
</ImportGroup> |
||||
</Project> |
@ -0,0 +1,321 @@ |
||||
#define OLC_PGE_APPLICATION |
||||
#include "olcPixelGameEngine.h" |
||||
|
||||
using namespace olc; |
||||
|
||||
// Override base class with your custom functionality
|
||||
class TicTacToe : public olc::PixelGameEngine |
||||
{ |
||||
public: |
||||
enum PieceType{ |
||||
BLANK, |
||||
CROSS, |
||||
CIRCLE |
||||
}; |
||||
|
||||
enum GameState{ |
||||
MENU, |
||||
PLAYING, |
||||
GAMEOVER |
||||
}; |
||||
|
||||
enum Winner{ |
||||
PLAYER_1, |
||||
PLAYER_2, |
||||
TIE |
||||
}; |
||||
|
||||
class Piece{ |
||||
public: |
||||
vi2d coord; |
||||
PieceType piece; |
||||
Piece() |
||||
:Piece({0,0},BLANK){} |
||||
Piece(vi2d coord,PieceType piece) |
||||
:coord(coord),piece(piece){}; |
||||
}; |
||||
|
||||
TicTacToe() |
||||
{ |
||||
// Name your application
|
||||
sAppName = "Tic-Tac-Toe"; |
||||
} |
||||
|
||||
Decal*circleImg; |
||||
Decal*crossImg; |
||||
Decal*gridImg; |
||||
|
||||
int pieceCount=5; |
||||
PieceType playerSide=CIRCLE; |
||||
PieceType opponentSide=CROSS; |
||||
|
||||
bool dragging=false; |
||||
|
||||
std::array<Piece,9>gamePieces; |
||||
|
||||
float aiThinkTime=0; |
||||
|
||||
bool playingAgainstAI=true; |
||||
GameState state=PLAYING; |
||||
Winner outcome=TIE; |
||||
|
||||
vf2d winLine1,winLine2; |
||||
|
||||
void SetOutcome(int score){ |
||||
if(score==3){ |
||||
outcome=PLAYER_1; |
||||
state=GAMEOVER; |
||||
}else |
||||
if(score==-3){ |
||||
outcome=PLAYER_2; |
||||
state=GAMEOVER; |
||||
} |
||||
} |
||||
|
||||
void AnalyzeBoard(){ |
||||
for(int row=0;row<3;row++){ |
||||
int rowScore=0; |
||||
for(int col=0;col<3;col++){ |
||||
int index=row*3+col; |
||||
PieceType gridPiece=gamePieces[index].piece; |
||||
if(gridPiece==BLANK){
|
||||
break;//This row is done...
|
||||
}else |
||||
if(gridPiece==playerSide){ |
||||
rowScore++; |
||||
}else{ |
||||
rowScore--; |
||||
} |
||||
} |
||||
if(abs(rowScore)==3){ |
||||
winLine1={0,float(row)}; |
||||
winLine2={2,float(row)}; |
||||
} |
||||
SetOutcome(rowScore); |
||||
} |
||||
for(int col=0;col<3;col++){ |
||||
int colScore=0; |
||||
for(int row=0;row<3;row++){ |
||||
int index=row*3+col; |
||||
PieceType gridPiece=gamePieces[index].piece; |
||||
if(gridPiece==BLANK){
|
||||
break;//This row is done...
|
||||
}else |
||||
if(gridPiece==playerSide){ |
||||
colScore++; |
||||
}else{ |
||||
colScore--; |
||||
} |
||||
} |
||||
if(abs(colScore)==3){ |
||||
winLine1={float(col),0}; |
||||
winLine2={float(col),2}; |
||||
} |
||||
SetOutcome(colScore); |
||||
} |
||||
|
||||
std::vector<vf2d>checkCoordsDiag1={{0,0},{1,1},{2,2}}; |
||||
std::vector<vf2d>checkCoordsDiag2={{0,2},{1,1},{2,0}}; |
||||
|
||||
int diag1Score=0; |
||||
for(vf2d&coord:checkCoordsDiag1){ |
||||
int index=coord.y*3+coord.x; |
||||
PieceType gridPiece=gamePieces[index].piece; |
||||
if(gridPiece==BLANK){
|
||||
break;//This row is done...
|
||||
}else |
||||
if(gridPiece==playerSide){ |
||||
diag1Score++; |
||||
}else{ |
||||
diag1Score--; |
||||
} |
||||
} |
||||
SetOutcome(diag1Score); |
||||
if(abs(diag1Score)==3){ |
||||
winLine1=checkCoordsDiag1[0]; |
||||
winLine2=checkCoordsDiag1[2]; |
||||
} |
||||
|
||||
int diag2Score=0; |
||||
for(vf2d&coord:checkCoordsDiag2){ |
||||
int index=coord.y*3+coord.x; |
||||
PieceType gridPiece=gamePieces[index].piece; |
||||
if(gridPiece==BLANK){
|
||||
break;//This row is done...
|
||||
}else |
||||
if(gridPiece==playerSide){ |
||||
diag2Score++; |
||||
}else{ |
||||
diag2Score--; |
||||
} |
||||
} |
||||
SetOutcome(diag2Score); |
||||
if(abs(diag2Score)==3){ |
||||
winLine1=checkCoordsDiag2[0]; |
||||
winLine2=checkCoordsDiag2[2]; |
||||
} |
||||
|
||||
bool allFilled=true; |
||||
for(int y=0;y<3;y++){ |
||||
for(int x=0;x<3;x++){ |
||||
int index=y*3+x; |
||||
if(gamePieces[index].piece==BLANK){ |
||||
allFilled=false; |
||||
} |
||||
} |
||||
} |
||||
if(outcome==TIE&&allFilled){ |
||||
state=GAMEOVER; |
||||
} |
||||
} |
||||
|
||||
public: |
||||
bool OnUserCreate() override |
||||
{ |
||||
// Called once at the start, so create things here
|
||||
for(int y=0;y<3;y++){ |
||||
for(int x=0;x<3;x++){ |
||||
int index=y*3+x; |
||||
gamePieces[index]=Piece({x,y},BLANK); |
||||
} |
||||
} |
||||
|
||||
circleImg=new Decal(new Sprite("circle.png")); |
||||
crossImg=new Decal(new Sprite("cross.png")); |
||||
gridImg=new Decal(new Sprite("grid.png")); |
||||
return true; |
||||
} |
||||
|
||||
bool OnUserUpdate(float fElapsedTime) override |
||||
{ |
||||
Clear({196,196,255}); |
||||
|
||||
switch(state){ |
||||
case MENU:{ |
||||
DrawStringDecal({0,0},"This is the menu."); |
||||
}break; |
||||
case PLAYING: |
||||
case GAMEOVER:{ |
||||
vf2d gridOffset={16,16}; |
||||
|
||||
Decal*pieceImg; |
||||
if(playerSide==CIRCLE){ |
||||
pieceImg=circleImg; |
||||
}else{ |
||||
pieceImg=crossImg; |
||||
} |
||||
|
||||
if(state==GAMEOVER){ |
||||
std::string gameOverText="Game is over!"; |
||||
std::string winnerText; |
||||
|
||||
if(playingAgainstAI){ |
||||
if(outcome==PLAYER_1){ |
||||
winnerText="You win!"; |
||||
} else{ |
||||
winnerText="AI wins!"; |
||||
} |
||||
}else{ |
||||
if(outcome==PLAYER_1){ |
||||
winnerText="Player 1 wins!"; |
||||
} else{ |
||||
winnerText="Player 2 wins!"; |
||||
} |
||||
} |
||||
|
||||
vf2d gameOverTextSize=vf2d(GetTextSize(gameOverText))*0.5; |
||||
vf2d winnerTextSize=vf2d(GetTextSize(winnerText))*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}); |
||||
}else{ |
||||
if(aiThinkTime>0){ |
||||
aiThinkTime-=fElapsedTime; |
||||
|
||||
if(aiThinkTime<=0){ |
||||
int chosenIndex=rand()%9; |
||||
while(gamePieces[chosenIndex].piece!=BLANK){ |
||||
chosenIndex=rand()%9; |
||||
} |
||||
gamePieces[chosenIndex].piece=opponentSide; |
||||
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}); |
||||
} |
||||
} |
||||
|
||||
for(int y=0;y<3;y++){ |
||||
for(int x=0;x<3;x++){ |
||||
int index=y*3+x; |
||||
vf2d upperLeftCorner=gridOffset+vf2d{x*32.f,y*32.f}; |
||||
vf2d lowerRightCorner=gridOffset+vf2d{x*32.f,y*32.f}+vf2d{32,32}; |
||||
|
||||
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(gamePieces[index].piece==BLANK){ |
||||
gamePieces[index].piece=playerSide; |
||||
dragging=false; |
||||
aiThinkTime=rand()%3+1; |
||||
AnalyzeBoard(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
switch(gamePieces[index].piece){ |
||||
case CROSS:{ |
||||
DrawDecal(gridOffset+vf2d{float(x),float(y)}*32,crossImg); |
||||
}break; |
||||
case CIRCLE:{ |
||||
DrawDecal(gridOffset+vf2d{float(x),float(y)}*32,circleImg); |
||||
}break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
if(GetMouseY()>120){ |
||||
FillRectDecal({0,120},{float(ScreenWidth()),40},{0,0,0,64}); |
||||
|
||||
if(GetMouse(Mouse::LEFT).bPressed){ |
||||
if(dragging){ |
||||
pieceCount++; |
||||
dragging=false; |
||||
}else |
||||
if(pieceCount>0){ |
||||
dragging=true; |
||||
pieceCount--; |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
DrawDecal(gridOffset,gridImg); |
||||
|
||||
if(dragging){ |
||||
DrawRotatedDecal(GetMousePos(),pieceImg,0,pieceImg->sprite->Size()/2); |
||||
} |
||||
|
||||
for(int i=0;i<pieceCount;i++){ |
||||
DrawDecal(vf2d{4.f+i*8,128},pieceImg); |
||||
} |
||||
}break; |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
}; |
||||
|
||||
int main() |
||||
{ |
||||
TicTacToe demo; |
||||
if (demo.Construct(128, 160, 4, 4)) |
||||
demo.Start(); |
||||
return 0; |
||||
} |
After Width: | Height: | Size: 788 B |
After Width: | Height: | Size: 745 B |
After Width: | Height: | Size: 751 B |
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue