Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 112 additions & 0 deletions ConnectX/backend/ConnectXBoard.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#include <stdexcept>
#include "ConnectXBoard.h"

int ConnectXBoard::numOccupied() const {
auto ctr = 0;
for (auto c : d) {
if (c != '.')
++ctr;
}
return ctr;
}

ConnectXBoard ConnectXBoard::makeMove(ConnectxMove move) {
if (isLegal(move)){
auto newDescr(d);
auto changedPos = findFirstFreePositionInCol(move.col);
newDescr[changedPos] = move.symbol;
return ConnectXBoard(newDescr);
} else {
throw std::invalid_argument("Received a bad move!");
}
}

int ConnectXBoard::findFirstFreePositionInCol(int c) const {
auto lastPositionInCol = c + (BOARD_SIZE -1) * BOARD_SIZE;
while (lastPositionInCol >= 0){
if (d[lastPositionInCol] == '.')
return lastPositionInCol;
else
lastPositionInCol -= BOARD_SIZE;
}
throw std::invalid_argument("Column is not free!");
}

bool ConnectXBoard::isLegal(ConnectxMove move) const {
if (move.col < 0 || move.col >= BOARD_SIZE)
return false;
if (d[move.col] != '.')
return false;
return true;
}

int ConnectXBoard::checkRow(int row) const {
auto start = row * BOARD_SIZE;
return checkLine(start, 1, start + BOARD_SIZE);
}

int ConnectXBoard::checkCol(int col) const {
return checkLine(col, BOARD_SIZE, BOARD_SIZE*BOARD_SIZE);
}

int ConnectXBoard::checkDiagonals() const {
// Diagonal 1
auto diag1 = checkLine(0, BOARD_SIZE + 1, BOARD_SIZE * BOARD_SIZE);
if (diag1 == 0){
return checkLine(BOARD_SIZE - 1, BOARD_SIZE - 1, BOARD_SIZE * BOARD_SIZE);
} else {
return diag1;
}
}

int ConnectXBoard::checkLine(int start, int increment, int topend) const {
if (d[start] == '.'){
return 0; //Not winning line
}
auto ctr = start + increment;
while (ctr < topend){
if (d[start] != d[ctr])
return 0;
ctr += increment;
}
if (d[start] == symbols[0]){
return 1;
} else {
return -1;
}
}

std::ostream & operator<<(std::ostream & os, const ConnectXBoard & board) {
for (auto i = 0; i < BOARD_SIZE*BOARD_SIZE; ++i){
os << board.getDescriptor()[i];
if (i % BOARD_SIZE == BOARD_SIZE - 1)
os << std::endl;
else
os << " ";
}
}

GameState ConnectXBoard::getGameState() const {
for (auto i = 0; i < BOARD_SIZE; ++i) {
auto score = checkRow(i);
if ( score != 0 )
return scoreToGameState(score);
}
for (auto i = 0; i < BOARD_SIZE; ++i){
auto score = checkCol(i);
if ( score != 0 )
return scoreToGameState(score);
}
return scoreToGameState(checkDiagonals());
}

inline
GameState ConnectXBoard::scoreToGameState(int score) const {
if (score == 1)
return Win1;
if (score == -1)
return Win2;
if (numOccupied() < BOARD_SIZE*BOARD_SIZE)
return Continue;
return Draw;
}
50 changes: 50 additions & 0 deletions ConnectX/backend/ConnectXBoard.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#ifndef GAMES_CONNECTXBOARD_H
#define GAMES_CONNECTXBOARD_H

#include <string>
#include <iostream>

/*
* Represents a board in a given position
*/
typedef enum {
Continue, Win1, Win2, Draw
} GameState;

const int BOARD_SIZE = 4;

typedef std::string descriptor;
typedef struct {
int col;
char symbol;
} ConnectxMove;

class ConnectXBoard {
public:
ConnectXBoard() :d(descriptor (16, '.')) {}
ConnectXBoard(const descriptor & descr) :d(descr) {}
ConnectXBoard(const ConnectXBoard& otherBoard) = default;
ConnectXBoard(ConnectXBoard&& otherBoard) = default;
int numOccupied() const;
GameState getGameState() const;

ConnectXBoard makeMove(ConnectxMove col);
const descriptor & getDescriptor() const { return d;}
bool isLegal(ConnectxMove col) const;
//const char& operator[] (int i) const { return d[i];}
//const char& operator[] (int i) { return d[i];}

static constexpr char symbols[2] = {'R', 'U'};
private:
const descriptor d;
int checkRow(int row) const ;
int checkCol(int col) const ;
int checkDiagonals() const ;
int checkLine(int start, int increment, int topend) const;
int findFirstFreePositionInCol(int c) const;
GameState scoreToGameState(int) const;
};

std::ostream& operator<< (std::ostream&, const ConnectXBoard&);

#endif //GAMES_CONNECTXBOARD_H
11 changes: 11 additions & 0 deletions ConnectX/backend/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include <iostream>
#include "ConnectXBoard.h"

int main () {
ConnectXBoard board;
std::cout << board.getDescriptor() << std::endl;
std::cout << board;
ConnectXBoard board1("R...RU..RU..RUU.");
std::cout << board1;
std::cout << board1.getGameState() << std::endl;
}