-
Notifications
You must be signed in to change notification settings - Fork 11
/
boardmatches.cpp
118 lines (84 loc) · 2.99 KB
/
boardmatches.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include "boardmatches.h"
#include <iostream>
#include <sstream>
#include <cassert>
#include <cstdlib>
MoveMatches::MoveMatches(Token player,int matches_taken) : Move(player), matches_taken(matches_taken) {}
void MoveMatches::print() const {
if (player!=NOT_PLAYED) std::cout<<"player "<<player<<" take "<<matches_taken<<" matches";
else std::cout<<"matches null move";
}
Move *MoveMatches::deepcopy() const {
Move *copy=new MoveMatches(player,matches_taken);
return copy;
}
bool MoveMatches::compare (const Move& abstract_move) const {
const auto &move=dynamic_cast<const MoveMatches&>(abstract_move);
return Move::compare(abstract_move) and matches_taken==move.matches_taken;
}
BoardMatches::BoardMatches(int matches_count) : matches_count(matches_count), last_player(NOT_PLAYED) {}
BoardMatches::~BoardMatches() = default;
Board *BoardMatches::deepcopy() const {
BoardMatches *copy=new BoardMatches(matches_count);
copy->last_player = last_player;
return copy;
}
Move *BoardMatches::parse_move_string(Token player,const char *string) const {
std::stringstream stream(std::stringstream::in | std::stringstream::out);
int matches_taken=-1;
stream<<string;
stream>>matches_taken;
if (stream.fail()) return NULL;
Move *move=new MoveMatches(player,matches_taken);
if (is_move_valid(*move)) return move;
delete move;
return NULL;
}
void BoardMatches::print() const {
std::cout << matches_count << " matches " << last_player << std::endl;
if (matches_count<=0) return;
for (int kk=0; kk<matches_count; kk++)
std::cout << "\e[31m█\e[0m ";
std::cout << std::endl;
for (int ll=0; ll<2; ll++) {
for (int kk=0; kk<matches_count; kk++)
std::cout << "║ ";
std::cout << std::endl;
}
}
bool BoardMatches::is_move_valid(const Move &abstract_move) const {
return is_move_valid(dynamic_cast<const MoveMatches&>(abstract_move));
}
bool BoardMatches::is_move_valid(const MoveMatches &move) const {
return move.player!=NOT_PLAYED and move.matches_taken>=1 and move.matches_taken<=3 and move.matches_taken<=matches_count;
}
Moves BoardMatches::get_possible_moves(Token player) const {
Moves moves;
for (int kk=1; kk<=3; kk++)
if (matches_count>=kk)
moves.push_back(new MoveMatches(player,kk));
return moves;
}
void BoardMatches::play_move(const Move &abstract_move) {
const MoveMatches &move=dynamic_cast<const MoveMatches&>(abstract_move);
assert(this->is_move_valid(move));
matches_count -= move.matches_taken;
last_player = move.player;
}
bool BoardMatches::play_random_move(Token player) {
if (matches_count<=0) return false;
//FIXME could be more efficient
Moves possible_moves=get_possible_moves(player);
int selected= static_cast<int>(rand() / (RAND_MAX + 1.0) * possible_moves.size());
Moves::const_iterator selected_iter=possible_moves.begin();
while (selected>0) {
selected--;
selected_iter++;
}
play_move(**selected_iter);
return true;
}
Token BoardMatches::check_for_win() const {
if (matches_count>0) return NOT_PLAYED;
return other_player(last_player);
}