123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- #include <iostream>
- #include "Game.h"
- #include "Types.h"
- Game::Game() : activeX(-1), activeY(-1) {
- reset();
- }
- void Game::reset() {
- activeX = -1;
- activeY = -1;
- for(uint x = 0; x < 9; x++) {
- for(uint y = 0; y < 5; y++) {
- fields[x][y] = (y > 2 ? FieldState::WHITE : FieldState::BLACK);
- }
- }
- fields[0][2] = FieldState::WHITE;
- fields[2][2] = FieldState::WHITE;
- fields[4][2] = FieldState::EMPTY;
- fields[5][2] = FieldState::WHITE;
- fields[7][2] = FieldState::WHITE;
- }
- void Game::reset(String& output) {
- reset();
- output.append("Fanorona Game\n");
- print(output);
- output.append("Human Color: White(O)\nAIColor: Black(#)\nHuman turn\nselect stone: ");
- }
- void Game::print(String& s) const {
- s.append("\n 0 1 2 3 4 5 6 7 8\n");
- printLine(s, 0);
- s.append(" |\\|/|\\|/|\\|/|\\|/|\n");
- printLine(s, 1);
- s.append(" |/|\\|/|\\|/|\\|/|\\|\n");
- printLine(s, 2);
- s.append(" |\\|/|\\|/|\\|/|\\|/|\n");
- printLine(s, 3);
- s.append(" |/|\\|/|\\|/|\\|/|\\|\n");
- printLine(s, 4);
- s.append('\n');
- }
- void Game::printLine(String& s, int index) const {
- static const char map[] = {
- '#', 'O', '.'
- };
- s.append(index + '0').append(' ');
- for(int x = 0; x < 8; x++) {
- if(x == activeX && index == activeY) {
- s.append("*-");
- continue;
- }
- s.append(map[fields[x][index]]).append('-');
- }
- if(8 == activeX && index == activeY) {
- s.append('*');
- } else {
- s.append(map[fields[8][index]]);
- }
- s.append('\n');
- }
- void Game::parse(const String& input, String& output) {
- if(input.getLength() <= 2 || !isDigit(input[0]) || input[1] != ' ' || !isDigit(input[2])) {
- revertToSelection(output);
- return;
- }
- uint x = input[0] - '0';
- uint y = input[2] - '0';
- if(x >= 9 || y >= 6) {
- revertToSelection(output);
- return;
- }
- if(activeX == -1 || activeY == -1) {
- markActive(x, y, output);
- } else {
- move(x, y, output);
- }
- }
- bool Game::isDigit(char c) const {
- return c >= '0' && c <= '9';
- }
- void Game::markActive(int x, int y, String& output) {
- if(fields[x][y] != FieldState::WHITE) {
- revertToSelection(output);
- return;
- }
- activeX = x;
- activeY = y;
- print(output);
- output.append("Human Color: White(O)\nAIColor: Black(#)\nselect location to move: ");
- }
- void Game::move(int x, int y, String& output) {
- if(fields[x][y] != FieldState::EMPTY || !areNeighbours(activeX, activeY, x, y)) {
- revertToSelection(output);
- return;
- }
- fields[activeX][activeY] = FieldState::EMPTY;
- fields[x][y] = FieldState::WHITE;
- removeLine(x, y, activeX, activeY, FieldState::BLACK);
- removeLine(activeX, activeY, x, y, FieldState::BLACK);
- activeX = x;
- activeY = y;
- print(output);
- output.append("Human Color: White(O)\nAIColor: Black(#)\n");
- print(output);
- output.append("Human Color: White(O)\nAIColor: Black(#)\nAI turn\n");
- activeX = -1;
- activeY = -1;
- botMove(output);
- }
- bool Game::areNeighbours(int x, int y, int x2, int y2) const {
- if(x == x2 && y == y2) {
- return false;
- }
- int diffX = x - x2;
- int diffY = y - y2;
- if(diffX < -1 || diffX > 1 || diffY < -1 || diffY > 1) {
- return false;
- }
- if(diffX == 0 || diffY == 0) {
- return true;
- }
- return !((x & 1) ^ (y & 1));
- }
- void Game::revertToSelection(String& output) {
- activeX = -1;
- activeY = -1;
- print(output);
- output.append("Human Color: White(O)\nAIColor: Black(#)\nHuman turn\nselect stone: ");
- }
- void Game::removeLine(int x, int y, int x2, int y2, FieldState remove) {
- int diffX = x2 - x;
- int diffY = y2 - y;
- while(true) {
- x2 += diffX;
- y2 += diffY;
- if(x2 < 0 || x2 >= 9 || y2 < 0 || y2 >= 5 || fields[x2][y2] != remove) {
- return;
- }
- fields[x2][y2] = FieldState::EMPTY;
- }
- }
- void Game::botMove(String& output) {
- while(true) {
- int x = 0;
- int y = 0;
- while(true) {
- x = rand() % 9;
- y = rand() % 5;
- if(fields[x][y] == FieldState::EMPTY) {
- break;
- }
- }
- for(uint i = 0; i < 10; i++) {
- int mx = x + (rand() % 3) - 1;
- int my = y + (rand() % 3) - 1;
- if((mx == x && my == y) || mx < 0 || mx >= 9 || my < 0 || my >= 5 || fields[mx][my] != FieldState::BLACK) {
- continue;
- }
- fields[mx][my] = FieldState::EMPTY;
- fields[x][y] = FieldState::BLACK;
- removeLine(mx, my, x, y, FieldState::WHITE);
- removeLine(x, y, mx, my, FieldState::WHITE);
-
- activeX = x;
- activeY = y;
- print(output);
- activeX = -1;
- activeY = -1;
- print(output);
- revertToSelection(output);
- return;
- }
- }
- }
|