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