Skip to content

Commit

Permalink
Upload original source files
Browse files Browse the repository at this point in the history
  • Loading branch information
Pharap authored Mar 15, 2018
1 parent 2499f38 commit 176833b
Show file tree
Hide file tree
Showing 5 changed files with 560 additions and 0 deletions.
385 changes: 385 additions & 0 deletions Game.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,385 @@
#pragma once

/*
Copyright (C) 2018 Pharap (@Pharap)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#define DISABLEAVRMIN
#include <Pokitto.h>

#include <algorithm>

#include "Grid.h"
#include "Point.h"

class Game
{
public:
enum class Status : unsigned char
{
Unfinished,
NoughtsWins,
CrossesWins,
Draw,
};

enum class Cell : unsigned char
{
None,
Nought,
Cross,
};

public:
using CellGrid = Grid<Cell, 3, 3>;
using PointType = Point<int>;

private:
CellGrid grid;
PointType selector;
Cell currentTurn = Cell::Nought;
Status status = Status::Unfinished;

public:
void run(void);

private:
void update(void);
void draw(void);

Status calculateStatus(void) const;
};

inline void Game::run(void)
{
Pokitto::Core::begin();

while (Pokitto::Core::isRunning())
{
if (Pokitto::Core::update())
{
this->update();
this->draw();
}
}
}

inline Game::Status Game::calculateStatus(void) const
{
PointType const winningSets[][3] =
{
// Vertical
{ PointType(0, 0), PointType(0, 1), PointType(0, 2) },
{ PointType(1, 0), PointType(1, 1), PointType(1, 2) },
{ PointType(2, 0), PointType(2, 1), PointType(2, 2) },

// Horizontal
{ PointType(0, 0), PointType(1, 0), PointType(2, 0) },
{ PointType(0, 1), PointType(1, 1), PointType(2, 1) },
{ PointType(0, 2), PointType(1, 2), PointType(2, 2) },

// Diagonal
{ PointType(0, 0), PointType(1, 1), PointType(2, 2) },
{ PointType(2, 0), PointType(1, 1), PointType(0, 2) },
};

for(auto const & line : winningSets)
{
PointType start = line[0];
Cell type = this->grid.getItem(start.x, start.y);

if(type == Cell::None)
continue;

bool success = true;
for(int i = 0; i < 3; ++i)
{
if(this->grid.getItem(line[i].x, line[i].y) != type)
{
success = false;
break;
}
}

if(success)
{
switch(type)
{
case Cell::Nought:
return Status::NoughtsWins;
case Cell::Cross:
return Status::CrossesWins;
default:
return Status::Unfinished;
}
}
}

bool hasEmptySpace = false;
for(int y = 0; y < 3 && !hasEmptySpace; ++y)
{
for(int x = 0; x < 3; ++x)
{
if(this->grid.getItem(x, y) == Cell::None)
{
hasEmptySpace = true;
break;
}
}
}

return hasEmptySpace ? Status::Unfinished : Status::Draw;
}

inline void Game::update(void)
{
if(Pokitto::Buttons::held(BTN_LEFT, 1))
{
if(this->selector.x > 0)
--this->selector.x;
}

if(Pokitto::Buttons::held(BTN_RIGHT, 1))
{
if(this->selector.x < 2)
++this->selector.x;
}

if(Pokitto::Buttons::held(BTN_UP, 1))
{
if(this->selector.y > 0)
--this->selector.y;
}

if(Pokitto::Buttons::held(BTN_DOWN, 1))
{
if(this->selector.y < 2)
++this->selector.y;
}

if(Pokitto::Buttons::held(BTN_A, 1))
{
if(this->grid.getItem(this->selector.x, this->selector.y) == Cell::None)
{
this->grid.getItem(this->selector.x, this->selector.y) = this->currentTurn;
switch(this->currentTurn)
{
case Cell::Nought:
this->currentTurn = Cell::Cross;
break;
case Cell::Cross:
this->currentTurn = Cell::Nought;
break;
default: break;
}

this->status = this->calculateStatus();
}
}

if(Pokitto::Buttons::held(BTN_B, 10) && this->status != Status::Unfinished)
{
this->grid.fill(Cell::None);
this->status = Status::Unfinished;
}
}

inline void Game::draw(void)
{
// Drawing parameters for easy modification
const int xGap = 8;
const int yGap = 8;
const int cellWidth = 32;
const int cellHeight = 32;

//const int blackIndex = 0;
const int whiteIndex = 1;

const int boardWidth = (cellWidth * 3 + xGap * 2);
const int boardHeight = (cellHeight * 3 + yGap * 2);

const int xOffset = (Pokitto::Display::getWidth() - boardWidth) / 2;
const int yOffset = (Pokitto::Display::getHeight() - boardHeight) / 2;

const int leftLineX = xOffset + (cellWidth * 1) + (xGap * 0) + (xGap / 2);
const int rightLineX = xOffset + (cellWidth * 2) + (xGap * 1) + (xGap / 2);

const int topLineY = yOffset + (cellHeight * 1) + (yGap * 0) + (yGap / 2);
const int bottomLineY = yOffset + (cellHeight * 2) + (yGap * 1) + (yGap / 2);

// Draw lines
Pokitto::Display::setColor(whiteIndex);

Pokitto::Display::drawLine(leftLineX, yOffset - 4, leftLineX, yOffset + boardHeight + 8);
Pokitto::Display::drawLine(rightLineX, yOffset - 4, rightLineX, yOffset + boardHeight + 8);

Pokitto::Display::drawLine(xOffset - 4, topLineY, xOffset + boardWidth + 8, topLineY);
Pokitto::Display::drawLine(xOffset - 4, bottomLineY, xOffset + boardWidth + 8, bottomLineY);


// Draw grid
for(int y = 0; y < 3; ++y)
{
for(int x = 0; x < 3; ++x)
{
const int cellX = xOffset + ((cellWidth + xGap) * x);
const int cellY = yOffset + ((cellHeight + yGap) * y);

// Draw symbol
switch(grid.getItem(x, y))
{
case Cell::Nought:
{
const int halfCellWidth = cellWidth / 2;
const int halfCellHeight = cellHeight / 2;
const int cellCentreX = cellX + halfCellWidth;
const int cellCentreY = cellY + halfCellHeight;
const int radius = std::min(halfCellWidth, halfCellHeight) - 1;

Pokitto::Display::drawCircle(cellCentreX, cellCentreY, radius);
break;
}
case Cell::Cross:
{
const int left = cellX + 1;
const int top = cellY + 1;
const int right = cellX + cellWidth - 1;
const int bottom = cellY + cellHeight - 1;

Pokitto::Display::drawLine(left, top, right, bottom);
Pokitto::Display::drawLine(right, top, left, bottom);
break;
}
default:
break;
}

// Draw selector
if(x == this->selector.x && y == this->selector.y)
{
Pokitto::Display::drawRect(cellX, cellY, cellWidth, cellHeight);
}
}
}

Pokitto::Display::setCursor(16, 8);
switch(this->status)
{
case Status::Unfinished:
{
switch(this->currentTurn)
{
case Cell::Nought:
{
Pokitto::Display::print("Player: Noughts");
break;
}
case Cell::Cross:
{
Pokitto::Display::print("Player: Crosses");
break;
}
case Cell::None:
{
Pokitto::Display::print("Error!?");
break;
}
}
break;
}
case Status::NoughtsWins:
{
Pokitto::Display::print("Noughts Wins!");
break;
}
case Status::CrossesWins:
{
Pokitto::Display::print("Crosses Wins!");
break;
}
case Status::Draw:
{
Pokitto::Display::print("Draw!");
break;
}
}
}

// Old version
/*inline void Game::draw(void)
{
// Drawing parameters for easy modification
const int xOffset = 16;
const int yOffset = 16;
const int xGap = 8;
const int yGap = 8;
const int cellWidth = 32;
const int cellHeight = 32;
const int boxColourIndex = 3;
const int symbolColourIndex = 0;
const int selectorColourIndex = 1;
// Draw grid
for(int y = 0; y < 3; ++y)
{
for(int x = 0; x < 3; ++x)
{
const int cellX = xOffset + ((cellWidth + xGap) * x);
const int cellY = yOffset + ((cellHeight + yGap) * y);
// Draw box
Pokitto::Display::setColor(boxColourIndex);
Pokitto::Display::fillRect(cellX, cellY, cellWidth, cellHeight);
// Draw symbol
Pokitto::Display::setColor(symbolColourIndex);
switch(grid.getItem(x, y))
{
case Cell::Nought:
{
const int halfCellWidth = cellWidth / 2;
const int halfCellHeight = cellHeight / 2;
const int cellCentreX = cellX + halfCellWidth;
const int cellCentreY = cellY + halfCellHeight;
const int radius = std::min(halfCellWidth, halfCellHeight) - 1;
Pokitto::Display::drawCircle(cellCentreX, cellCentreY, radius);
break;
}
case Cell::Cross:
{
const int left = cellX + 1;
const int top = cellY + 1;
const int right = cellX + cellWidth - 1;
const int bottom = cellY + cellHeight - 1;
Pokitto::Display::drawLine(left, top, right, bottom);
Pokitto::Display::drawLine(right, top, left, bottom);
break;
}
default:
break;
}
// Draw selector
if(x == this->selector.x && y == this->selector.y)
{
Pokitto::Display::setColor(selectorColourIndex);
Pokitto::Display::drawRect(cellX, cellY, cellWidth, cellHeight);
}
}
}
}*/
Loading

0 comments on commit 176833b

Please sign in to comment.