Skip to content

Commit

Permalink
A few bugfixes. PvP works, but issue #13 blocks PvE
Browse files Browse the repository at this point in the history
  • Loading branch information
aryjczyk committed Mar 8, 2013
1 parent 474297b commit 3af0453
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 18 deletions.
63 changes: 59 additions & 4 deletions ataxx-engine/AtaxxEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ namespace engine
static const unsigned BOARD_WB_WIDTH = 11;
static const unsigned BOARD_WB_HEIGHT = 11;

static const int BOARD_SINGLE_BORDER = 1;
//WSB is short for "with single border"
static const unsigned BOARD_WSB_SIZE = 81;
static const unsigned BOARD_WSB_WIDTH = 9;
static const unsigned BOARD_WSB_HEIGHT = 9;

static const uint8_t COMPRESSED_EMPTY = 0x0;
static const uint8_t COMPRESSED_P1 = 0x1;
static const uint8_t COMPRESSED_P2 = 0x2;
Expand Down Expand Up @@ -56,7 +62,26 @@ namespace engine
memset(buffer, GameState::BLOCKED, BOARD_WB_SIZE * sizeof(GameState::FieldState));
for(unsigned i = 0; i < BOARD_HEIGHT; ++i)
{
memcpy(buffer + BOARD_BORDER + (i + BOARD_BORDER) * BOARD_WB_WIDTH, State.board,
memcpy(buffer + BOARD_BORDER + (i + BOARD_BORDER) * BOARD_WB_WIDTH, State.board + i * BOARD_WIDTH,
BOARD_WIDTH * sizeof(GameState::FieldState));
}
}
//TODO: get rid of code duplication. probably template?
void copyWithSingleBorder(const GameState& State, GameState::FieldState (&buffer)[BOARD_WSB_SIZE])
{
memset(buffer, GameState::BLOCKED, BOARD_WSB_SIZE * sizeof(GameState::FieldState));
for(unsigned i = 0; i < BOARD_HEIGHT; ++i)
{
memcpy(buffer + BOARD_SINGLE_BORDER + (i + BOARD_SINGLE_BORDER) * BOARD_WSB_WIDTH, State.board + i * BOARD_WIDTH,
BOARD_WIDTH * sizeof(GameState::FieldState));
}
}

void stripSingleBorderAndCopy( GameState* State, GameState::FieldState* board )
{
for(unsigned i = 0; i < BOARD_HEIGHT; ++i)
{
memcpy(State->board + i * BOARD_WIDTH, board + BOARD_SINGLE_BORDER + (i + BOARD_SINGLE_BORDER) * BOARD_WSB_WIDTH,
BOARD_WIDTH * sizeof(GameState::FieldState));
}
}
Expand Down Expand Up @@ -119,10 +144,10 @@ namespace engine
// also takes coordinates for bordered board
bool canJumpFromTo(GameState::Player player, GameState::FieldState (&board)[BOARD_WB_SIZE], unsigned fromX, unsigned fromY, unsigned toX, unsigned toY)
{
assert(diffBiggerThan(fromX, toX) || diffBiggerThan(fromY, toY));
assert(!diffBiggerThan(fromX, toX) && !diffBiggerThan(fromY, toY));
assert(board[toY * BOARD_WB_WIDTH + toX] != GameState::BLOCKED);
assert(diffEqual(fromX, toX) || diffEqual(fromY, toY));
if(board[fromY * BOARD_WB_WIDTH + fromX] == player)
if(board[fromY * BOARD_WB_WIDTH + fromX] == player && board[toY * BOARD_WB_WIDTH + toX] == GameState::EMPTY)
{
return true;
}
Expand Down Expand Up @@ -542,6 +567,7 @@ namespace engine

while(genLastX < BOARD_BORDER + BOARD_WIDTH && genLastY < BOARD_BORDER + BOARD_HEIGHT && i < bufferSize)
{
//that is uninitialized read only thingy - wtf?
*genBufferU[i] = genCurrent;
if(genCurrent.player == GameState::ONE)
{
Expand All @@ -566,10 +592,11 @@ namespace engine
{
if(possibleMoves[genLastY * BOARD_WB_WIDTH + genLastX].clone)
{
// what about explicitly assigning P_1 to ONE and P_2 to TWO to eliminate if?
genBufferU[i] -> board[(genLastY - 2) * BOARD_WIDTH + genLastX - 2] =
genCurrent.player == GameState::ONE ?
GameState::P_1 :
GameState::P_2;
GameState::P_2;
}
i++;
putClone = true;
Expand Down Expand Up @@ -692,9 +719,32 @@ namespace engine
Current->board[to.y * BOARD_WIDTH + to.x] = GameState::P_2;
Current->player = GameState::ONE;
}
switchPiecesOwner(Current, to);
return Current;
}

void switchPiecesOwner(GameState* State, CoordU& newPiece)
{
GameState::FieldState board[BOARD_WSB_SIZE];
copyWithSingleBorder(*State, board);
GameState::FieldState oldOwner =
board[newPiece.x + BOARD_SINGLE_BORDER + BOARD_WSB_WIDTH * (newPiece.y + BOARD_SINGLE_BORDER)] == GameState::P_1 ?
GameState::P_2 : GameState::P_1;
GameState::FieldState newOwner = board[newPiece.x + BOARD_SINGLE_BORDER + BOARD_WSB_WIDTH * (newPiece.y + BOARD_SINGLE_BORDER)];
for(int i = -1; i <= 1; ++i)
{
for (int ii = -1; ii <= 1; ++ii)
{
unsigned currentField = newPiece.x + i + BOARD_SINGLE_BORDER + BOARD_WSB_WIDTH * (newPiece.y + BOARD_SINGLE_BORDER + ii);
if(board[currentField] == oldOwner)
{
board[currentField] = newOwner;
}
}
}
stripSingleBorderAndCopy(State, board);
}

CompressedState* getInitialStateComp()
{
//see above
Expand Down Expand Up @@ -734,4 +784,9 @@ namespace engine
{
return sizeof(GameState);
}

bool canMoveFrom( engine::GameState* currentGameState, CoordU from )
{
return currentGameState->board[from.x + BOARD_WIDTH * from.y] == currentGameState->player;
}
}
8 changes: 7 additions & 1 deletion ataxx-engine/AtaxxEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "../interfaces/CommonEngine.h"

//rationale: typed enum is supported in other compilers
#ifdef _WIN32
#ifdef _MSC_VER
#pragma warning(disable: 4480)
#endif

Expand Down Expand Up @@ -60,4 +60,10 @@ namespace engine
*/
GameState* decompress(const CompressedState* const State, GameState* Out);

/// \brief switches ownership of pieces around newPiece to it's owner
void switchPiecesOwner(GameState* State, CoordU& newPiece);

/// \brief copies from board with border to State
void stripSingleBorderAndCopy( GameState* State, GameState::FieldState* board );

}
3 changes: 3 additions & 0 deletions interfaces/CommonEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,7 @@ namespace engine

/// \brief returns GameState size in bytes
unsigned getGameStateSize();

/// \brief indicates if current player can move a piece located at coords from
bool canMoveFrom( engine::GameState* currentGameState, CoordU from );
}
36 changes: 30 additions & 6 deletions main/LocalHuman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <iostream>



LocalHuman::LocalHuman(void)
{
}
Expand All @@ -14,17 +15,40 @@ LocalHuman::~LocalHuman(void)

engine::GameState* LocalHuman::move( engine::GameState* currentGameState )
{
bool moveCompleted = false;
CoordU to;
bool moveCompleted = false, pieceChosen = false;
CoordU from, to;
std::cout << "Which piece would you like to move?\n";
while(!pieceChosen)
{
std::cin >> from.x >> from.y;
pieceChosen = engine::canMoveFrom(currentGameState, from);
if(!pieceChosen || !std::cin.good())
{
if(!std::cin.good())
{
std::cin.sync();
std::cin.clear();
pieceChosen = false;
}
std::cout << "You don't have a piece at these coordinates. Try again\n";
}
}
std::cout << "Where do you want to move?\n";
while(!moveCompleted)
{
std::cin >> to.x >> to.y;
//TODO: add to header, bool isMoveValid(GameState current, CoordU from, CoordU to);
//Note, that this function will probably be unnecessary after implementing public state
moveCompleted = engine::isMoveValid(currentGameState, CoordU(), to);
if(!moveCompleted)
moveCompleted = engine::isMoveValid(currentGameState, from, to);
if(!moveCompleted || !std::cin.good())
{
if(!std::cin.good())
{
std::cin.sync();
std::cin.clear();
moveCompleted = false;
}
std::cout << "It is not a valid move. Please enter another one\n";
}
}
return engine::makeMove(currentGameState, CoordU(), to);//note: same as above
return engine::makeMove(currentGameState, from, to);//note: same as above
}
4 changes: 2 additions & 2 deletions main/RandomAlgo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace algo

RandomAlgo::~RandomAlgo()
{

freeAllStates();
}

engine::GameState* RandomAlgo::chooseMove(const engine::GameState * const currentState)
Expand All @@ -37,7 +37,7 @@ namespace algo
{
engine::GameState** newBuffer = new engine::GameState* [STATE_BUFFER_SIZE];
possibleMoves.push_back(newBuffer);
memcpy(*possibleMoves.back(), &stateBuffer, sizeof(engine::GameState*) * STATE_BUFFER_SIZE);
memcpy(possibleMoves.back(), stateBuffer, sizeof(engine::GameState*) * STATE_BUFFER_SIZE);
}

engine::GameState* RandomAlgo::getMove(unsigned moveIndex)
Expand Down
15 changes: 10 additions & 5 deletions main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ void printWinner( engine::GameResult result )
std::cout << "It is a draw\n";
break;
}
system("PAUSE");
}

void cleanUp(Player** players)
Expand All @@ -69,10 +70,13 @@ int main()

while(engine::gameFinished(currentGameState) == engine::NOT_FINISHED)
{
currentGameState = players[playerActive]->move(currentGameState);
playerActive = nextPlayer(playerActive);
if(localDebug)
{
std::cout << "Player " << playerActive + 1<< " turn\n";
printBoard(currentGameState);
}
currentGameState = players[playerActive]->move(currentGameState);
playerActive = nextPlayer(playerActive);
}
printWinner(engine::gameFinished(currentGameState));

Expand Down Expand Up @@ -115,13 +119,14 @@ gameMode_t askForMode()

void printBoard( engine::GameState *encodedState )
{
char printable[3] = {'-', '1', '2'};
const int BOARD_SIZE = 7;
engine::PublicState gameState = engine::convertToPublic(encodedState);
for(int i = 0; i < BOARD_SIZE; ++i)
{
for(int i2 = 0; i2 < BOARD_SIZE; ++i2)
{
std::cout << gameState.board[i * BOARD_SIZE + i2];
std::cout << printable[gameState.board[i * BOARD_SIZE + i2]];
}
std::cout << "\n";
}
Expand All @@ -140,8 +145,8 @@ void setupPlayers( gameMode_t gameMode, Player ** player1, Player ** player2 )
}
case PVE:
{
*player1 = new Computer;
*player2 = new LocalHuman;
*player1 = new LocalHuman;
*player2 = new Computer;
break;
}
case PVP:
Expand Down
2 changes: 2 additions & 0 deletions main/main.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatWarningAsError>true</TreatWarningAsError>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
Expand All @@ -64,6 +65,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<TreatWarningAsError>true</TreatWarningAsError>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
Expand Down

0 comments on commit 3af0453

Please sign in to comment.