Implemented Board, and finished up the monopoly code.

This commit is contained in:
Relintai 2021-03-29 11:43:59 +02:00
parent 3c695a3bac
commit a2ae9406b5
13 changed files with 504 additions and 38 deletions

209
03_monopoly/board.cpp Normal file
View File

@ -0,0 +1,209 @@
#include "board.h"
#include <cstdio>
#include "player_loader.h"
#include "tile_loader.h"
Player *Board::get_current_player() {
return _active_players[_current_player_index];
}
Player *Board::get_previous_player() {
return _previous_player;
}
int Board::get_turn() const {
return _turn;
}
void Board::set_turn(const int turn) {
_turn = turn;
}
Vector<Tile *> Board::get_tiles() const {
return _tiles;
}
void Board::set_tiles(const Vector<Tile *> &tiles) {
_tiles = tiles;
}
Vector<Player *> Board::get_active_players() const {
return _active_players;
}
void Board::set_active_players(const Vector<Player *> &players) {
_active_players = players;
}
Vector<Player *> Board::get_lost_players() const {
return _lost_players;
}
void Board::set_lost_players(const Vector<Player *> &players) {
_lost_players = players;
}
void Board::load(const String &tile_file, const String &player_file) {
clear();
_tiles = TileLoader::load_tile_file(tile_file);
_active_players = PlayerLoader::load_player_file(player_file);
}
void Board::load_players(const String &file) {
clear_players();
_active_players = PlayerLoader::load_player_file(file);
}
void Board::load_tiles(const String &file) {
for (int i = 0; i < _tiles.size(); ++i) {
delete _tiles[i];
}
_tiles = TileLoader::load_tile_file(file);
}
void Board::step() {
Player *cp = _active_players[_current_player_index];
printf("Player - %s's turn.\n", cp->get_name().c_str());
int jail_time = cp->get_jail_time();
if (jail_time > 0) {
--jail_time;
printf("Player - is in jail for %d more turns.\n", jail_time);
cp->set_jail_time(jail_time);
return;
}
int t = cp->throw_dice();
int ti = cp->get_tile_index();
ti += t;
if (ti >= _tiles.size()) {
ti = t % _tiles.size();
}
cp->set_tile_index(ti);
Tile *tile = _tiles[ti];
tile->on_player_arrived(cp);
_previous_player = cp;
if (cp->get_lost()) {
_active_players.remove_keep_order(_current_player_index);
_lost_players.push_back(cp);
if (_current_player_index >= _active_players.size()) {
_current_player_index = 0;
}
return;
}
++_current_player_index;
if (_current_player_index >= _active_players.size()) {
_current_player_index = 0;
}
}
void Board::run() {
while (_active_players.size() > 1 && _turn < 200) {
step();
++_turn;
}
on_game_finished();
}
void Board::on_game_finished() {
if (_active_players.size() != 1) {
printf("The game has been finished! No winner!\n");
} else {
printf("The game has been finished! %s the winner!\n", _active_players[0]->get_name().c_str());
}
printf("The game took %d turns!\n", _turn);
}
void Board::clear() {
for (int i = 0; i < _tiles.size(); ++i) {
delete _tiles[i];
}
for (int i = 0; i < _active_players.size(); ++i) {
delete _active_players[i];
}
for (int i = 0; i < _lost_players.size(); ++i) {
delete _lost_players[i];
}
_tiles.clear();
_active_players.clear();
_lost_players.clear();
}
void Board::clear_players() {
for (int i = 0; i < _active_players.size(); ++i) {
delete _active_players[i];
}
for (int i = 0; i < _lost_players.size(); ++i) {
delete _lost_players[i];
}
_active_players.clear();
_lost_players.clear();
}
void Board::reset() {
_previous_player = nullptr;
_current_player_index = 0;
_turn = 0;
for (int i = 0; i < _tiles.size(); ++i) {
_tiles[i]->reset();
}
clear_players();
}
void Board::print() {
printf("Board:\n");
printf("Tiles:\n");
for (int i = 0; i < _tiles.size(); ++i) {
_tiles[i]->print();
}
printf("Active players (%d):\n", _active_players.size());
for (int i = 0; i < _active_players.size(); ++i) {
_active_players[i]->print();
}
printf("Lost players (%d):\n", _lost_players.size());
for (int i = 0; i < _lost_players.size(); ++i) {
_lost_players[i]->print();
}
}
Board::Board() {
reset();
}
Board::Board(const String &tile_file, const String &player_file) {
reset();
load(tile_file, player_file);
}
Board::~Board() {
clear();
}

55
03_monopoly/board.h Normal file
View File

@ -0,0 +1,55 @@
#ifndef BOARD_H
#define BOARD_H
#include "player.h"
#include "string.h"
#include "tile.h"
#include "vector.h"
class Board {
public:
Player *get_current_player();
Player *get_previous_player();
int get_turn() const;
void set_turn(const int turn);
Vector<Tile *> get_tiles() const;
void set_tiles(const Vector<Tile *> &tiles);
Vector<Player *> get_active_players() const;
void set_active_players(const Vector<Player *> &players);
Vector<Player *> get_lost_players() const;
void set_lost_players(const Vector<Player *> &players);
void load(const String &tile_file, const String &player_file);
void load_players(const String &file);
void load_tiles(const String &file);
void step();
void run();
void on_game_finished();
void clear();
void clear_players();
void reset();
void print();
Board();
Board(const String &tile_file, const String &player_file);
virtual ~Board();
private:
Vector<Tile *> _tiles;
Vector<Player *> _active_players;
Vector<Player *> _lost_players;
Player *_previous_player;
int _current_player_index;
int _turn;
};
#endif

View File

@ -18,6 +18,8 @@ g++ -Wall -g -c player.cpp -o obj/player.o
g++ -Wall -g -c player_loader.cpp -o obj/player_loader.o
g++ -Wall -g -c tile_loader.cpp -o obj/tile_loader.o
g++ -Wall -g -c main.cpp -o obj/main.o
g++ -o bin/program obj/string.o obj/math.o obj/tile.o obj/tile_loader.o obj/player.o obj/player_loader.o obj/main.o
g++ -Wall -g -c board.cpp -o obj/board.o
g++ -Wall -g -c main.cpp -o obj/main.o
g++ -g -o bin/program obj/string.o obj/math.o obj/tile.o obj/tile_loader.o obj/player.o obj/player_loader.o obj/board.o obj/main.o

View File

@ -10,18 +10,19 @@
#include "tile_loader.h"
#include "player_loader.h"
#include "board.h"
#include "math.h"
int main() {
Math::randomize();
Vector<Tile *> tiles = TileLoader::load_tile_file("tiles.config");
Vector<Player *> players = PlayerLoader::load_player_file("players.config");
Board b;
b.load("tiles.config", "players.config");
for (int i = 0; i < tiles.size(); ++i) {
tiles[i]->print();
}
b.run();
for (int i = 0; i < players.size(); ++i) {
players[i]->print();
}
b.print();
return 0;
}

View File

@ -2,6 +2,8 @@
#include <stdio.h>
#include "math.h"
String Player::get_name() {
return _name;
}
@ -23,7 +25,21 @@ int Player::get_money() const {
}
void Player::set_money(const int val) {
int c = _money - val;
if (c >= 0) {
printf("Player - %s has gained %d dollars.\n", _name.c_str(), c);
} else {
printf("Player - %s has gained %d dollars.\n", _name.c_str(), -c);
}
_money = val;
if (_money <= 0) {
_money = 0;
set_lost(true);
}
}
int Player::get_jail_time() const {
@ -31,6 +47,10 @@ int Player::get_jail_time() const {
}
void Player::set_jail_time(const int val) {
if (_jail_time == 0) {
printf("Player - %s has been jailed for %d turns.\n", _name.c_str(), val);
}
_jail_time = val;
}
@ -40,19 +60,26 @@ bool Player::get_lost() const {
void Player::set_lost(const bool val) {
_lost = val;
if (val) {
on_lose();
}
}
bool Player::want_buy(const String &tile_name, int price) {
return false;
}
void Player::pay_entry_fee(const int val, Player *to) {
}
int Player::throw_dice() {
int t = Math::rand(1, 7);
void Player::throw_dice() {
printf("Player - %s has thrown the dice, and rolled %d.\n", _name.c_str(), t);
return t;
}
void Player::on_lose() {
printf("Player - %s has lost the game. And he's sad.\n", _name.c_str());
}
void Player::print() {
@ -77,6 +104,7 @@ bool AgressivePlayer::want_buy(const String &tile_name, int price) {
return false;
}
void AgressivePlayer::on_lose() {
printf("Player - %s has lost the game. And he's angry.\n", _name.c_str());
}
String AgressivePlayer::get_class_name() {
return "AgressivePlayer";
@ -101,6 +129,7 @@ bool TrickyPlayer::want_buy(const String &tile_name, int price) {
return false;
}
void TrickyPlayer::on_lose() {
printf("Player - %s has lost the game.\n", _name.c_str());
}
String TrickyPlayer::get_class_name() {
return "TrickyPlayer";
@ -113,6 +142,7 @@ bool HumanPlayer::want_buy(const String &tile_name, int price) {
return false;
}
void HumanPlayer::on_lose() {
printf("Player - %s has lost the game. And he's really sad.\n", _name.c_str());
}
String HumanPlayer::get_class_name() {
return "HumanPlayer";
@ -124,9 +154,15 @@ HumanPlayer::HumanPlayer() :
bool CheatingPlayer::want_buy(const String &tile_name, int price) {
return false;
}
void CheatingPlayer::throw_dice() {
int CheatingPlayer::throw_dice() {
int t = Math::rand(3, 7);
printf("Player - %s has thrown the dice, and rolled %d.\n", _name.c_str(), t);
return t;
}
void CheatingPlayer::on_lose() {
printf("Player - %s has lost the game. And he's really angry.\n", _name.c_str());
}
String CheatingPlayer::get_class_name() {
return "CheatingPlayer";

View File

@ -21,8 +21,7 @@ public:
void set_lost(const bool val);
virtual bool want_buy(const String &tile_name, int price);
virtual void pay_entry_fee(const int val, Player *to);
virtual void throw_dice();
virtual int throw_dice();
virtual void on_lose();
virtual void print();
@ -83,7 +82,7 @@ public:
class CheatingPlayer : public Player {
public:
bool want_buy(const String &tile_name, int price);
void throw_dice();
int throw_dice();
void on_lose();
String get_class_name();

View File

@ -39,12 +39,11 @@ Vector<Player *> PlayerLoader::load_player_file(const String &file_name) {
f >> money >> name;
p->set_money(money);
String n(name.c_str());
p->set_name(n);
p->set_money(money);
players.push_back(p);
}
}

View File

@ -258,6 +258,10 @@ String::String() {
_actual_size = 0;
_size = 0;
_grow_by = 100;
ensure_capacity(100);
_data[0] = '\0';
}
String::String(const String &other) {
@ -272,6 +276,8 @@ String::String(const String &other) {
for (int i = 0; i < other._size; ++i) {
_data[i] = other._data[i];
}
_data[other._size] = '\0';
}
String::String(const String &other, int grow_by) {

View File

@ -2,6 +2,8 @@
#include <stdio.h>
#include "math.h"
String Tile::get_name() {
return _name;
}
@ -11,6 +13,11 @@ void Tile::set_name(const String &name) {
}
void Tile::on_player_arrived(Player *p) {
printf("Player %s just stepped on %s.\n", p->get_name().c_str(), _name.c_str());
}
void Tile::reset() {
}
void Tile::print() {
@ -31,9 +38,16 @@ int TaxTile::get_tax() const {
return _tax;
}
void TaxTile::set_tax(const int tax) {
_tax = tax;
}
void TaxTile::on_player_arrived(Player *p) {
Tile::on_player_arrived(p);
p->set_money(p->get_money() - _tax);
}
void TaxTile::print() {
printf("Tile - %s - Name: %s, tax: %d\n", get_class_name().c_str(), get_name().c_str(), _tax);
}
String TaxTile::get_class_name() {
return "TaxTile";
@ -41,6 +55,8 @@ String TaxTile::get_class_name() {
TaxTile::TaxTile() :
Tile() {
_tax = 0;
}
int OwnableTile::get_price() const {
@ -65,6 +81,49 @@ void OwnableTile::set_owner(Player *val) {
}
void OwnableTile::on_player_arrived(Player *p) {
Tile::on_player_arrived(p);
if (!_owner) {
printf("Tile - %s is for sale! It costs %d.\n", get_name().c_str(), _price);
int m = p->get_money();
if (m < _price) {
printf("Player - %s, can't buy tile, not enough money!\n", p->get_name().c_str());
return;
}
printf("Player - %s, do you want to buy?\n", p->get_name().c_str());
if (p->want_buy(get_name(), _price)) {
printf("Player - %s now owns %s.\n", p->get_name().c_str(), get_name().c_str());
_owner = p;
}
} else {
if (p == _owner) {
printf("Tile - %s is now owned by you. Welcome!\n", get_name().c_str());
return;
}
printf("Tile - %s is owned by %s. You need to pay an entry fee of %d!\n", get_name().c_str(), p->get_name().c_str(), _enter_price);
int m = p->get_money();
if (m <= _enter_price) {
_owner->set_money(_owner->get_money() + m);
p->set_money(0);
} else {
_owner->set_money(_owner->get_money() + _enter_price);
p->set_money(m - _enter_price);
}
}
}
void OwnableTile::print() {
printf("Tile - %s - Name: %s, price: %d, enter_price: %d, owner: %s.\n", get_class_name().c_str(), get_name().c_str(), _price, _enter_price, _owner ? _owner->get_name().c_str() : "None");
}
void OwnableTile::reset() {
_owner = nullptr;
}
String OwnableTile::get_class_name() {
return "OwnableTile";
@ -72,6 +131,10 @@ String OwnableTile::get_class_name() {
OwnableTile::OwnableTile() :
Tile() {
_price = 0;
_enter_price = 0;
_owner = nullptr;
}
int GainTile::get_gain() const {
@ -82,6 +145,12 @@ void GainTile::set_gain(const int val) {
}
void GainTile::on_player_arrived(Player *p) {
Tile::on_player_arrived(p);
p->set_money(p->get_money() - _gain);
}
void GainTile::print() {
printf("Tile - %s - Name: %s, gain: %d.\n", get_class_name().c_str(), get_name().c_str(), _gain);
}
String GainTile::get_class_name() {
return "GainTile";
@ -89,6 +158,8 @@ String GainTile::get_class_name() {
GainTile::GainTile() :
Tile() {
_gain = 0;
}
int LuckTile::get_chance() const {
@ -113,6 +184,18 @@ void LuckTile::set_gain_max(const int val) {
}
void LuckTile::on_player_arrived(Player *p) {
Tile::on_player_arrived(p);
int c = Math::rand(0, 100);
if (c < _chance) {
int v = Math::rand(_gain_min, _gain_max);
p->set_money(p->get_money() + v);
}
}
void LuckTile::print() {
printf("Tile - %s - Name: %s, chance: %d, gain_min: %d, gain_max: %d.\n", get_class_name().c_str(), get_name().c_str(), _chance, _gain_min, _gain_max);
}
String LuckTile::get_class_name() {
return "LuckTile";
@ -120,6 +203,10 @@ String LuckTile::get_class_name() {
LuckTile::LuckTile() :
Tile() {
_chance = 0;
_gain_min = 0;
_gain_max = 0;
}
int JailTile::get_jail_time() const {
@ -130,6 +217,12 @@ void JailTile::set_jail_time(const int val) {
}
void JailTile::on_player_arrived(Player *p) {
Tile::on_player_arrived(p);
p->set_jail_time(_jail_time);
}
void JailTile::print() {
printf("Tile - %s - Name: %s, jail_time: %d.\n", get_class_name().c_str(), get_name().c_str(), _jail_time);
}
String JailTile::get_class_name() {
return "JailTile";
@ -137,4 +230,6 @@ String JailTile::get_class_name() {
JailTile::JailTile() :
Tile() {
_jail_time = 0;
}

View File

@ -10,6 +10,8 @@ public:
virtual void on_player_arrived(Player *p);
virtual void reset();
virtual void print();
virtual String get_class_name();
@ -26,6 +28,7 @@ public:
void set_tax(const int tax);
void on_player_arrived(Player *p);
void print();
String get_class_name();
TaxTile();
@ -46,6 +49,9 @@ public:
void set_owner(Player *val);
void on_player_arrived(Player *p);
void print();
void reset();
String get_class_name();
OwnableTile();
@ -62,6 +68,7 @@ public:
void set_gain(const int val);
void on_player_arrived(Player *p);
void print();
String get_class_name();
GainTile();
@ -82,6 +89,7 @@ public:
void set_gain_max(const int val);
void on_player_arrived(Player *p);
void print();
String get_class_name();
LuckTile();
@ -98,6 +106,7 @@ public:
void set_jail_time(const int val);
void on_player_arrived(Player *p);
void print();
String get_class_name();
JailTile();

View File

@ -1,8 +1,8 @@
#include "tile_loader.h"
#include "tile.h"
#include <fstream>
#include <string>
#include "tile.h"
Vector<Tile *> TileLoader::load_tile_file(const String &file_name) {
Vector<Tile *> tiles;
@ -14,31 +14,70 @@ Vector<Tile *> TileLoader::load_tile_file(const String &file_name) {
while (!f.eof()) {
std::string class_name;
std::string tile_name;
f >> class_name;
f >> class_name >> tile_name;
Tile *t = nullptr;
Tile *t = nullptr;
if (class_name == "Tile") {
t = new Tile();
} else if (class_name == "TaxTile") {
t = new TaxTile();
TaxTile *tt = new TaxTile();
int tax;
f >> tax;
tt->set_tax(tax);
t = tt;
} else if (class_name == "OwnableTile") {
t = new OwnableTile();
OwnableTile *tt = new OwnableTile();
int price;
int enter_price;
f >> price >> enter_price;
tt->set_price(price);
tt->set_enter_price(enter_price);
t = tt;
} else if (class_name == "GainTile") {
t = new GainTile();
GainTile *tt = new GainTile();
int gain;
f >> gain;
tt->set_gain(gain);
t = tt;
} else if (class_name == "LuckTile") {
t = new LuckTile();
LuckTile *tt = new LuckTile();
int chance;
int gain_min;
int gain_max;
f >> chance >> gain_min >> gain_max;
tt->set_chance(chance);
tt->set_gain_min(gain_min);
tt->set_gain_max(gain_max);
t = tt;
} else if (class_name == "JailTile") {
t = new JailTile();
JailTile *tt = new JailTile();
int jail_time;
f >> jail_time;
tt->set_jail_time(jail_time);
t = tt;
}
if (t) {
std::string name;
f >> name;
String n(name.c_str());
String n(tile_name.c_str());
t->set_name(n);

View File

@ -1,6 +1,12 @@
Tile Asf
TaxTile aAA
OwnableTile fqfqfdg
GainTile fffqq
LuckTile Qewew
JailTile Fqqfq
TaxTile aAA 3433
TaxTile dqdq 3433
OwnableTile fqfqfdg 222 22
GainTile fffqq 100
TaxTile aArrrrA 3433
LuckTile Qewew 50 100 200
TaxTile dqwd 3433
JailTile Fqqfq 3
TaxTile qweq 3433
TaxTile qweq 3433
TaxTile qweqw 3433

View File

@ -8,6 +8,7 @@ public:
void push_back(const T &element);
void pop_back();
void remove(const int index);
void remove_keep_order(const int index);
void erase(const T &element);
void clear();
bool empty() const;
@ -62,6 +63,15 @@ void Vector<T>::remove(const int index) {
--_size;
}
template <class T>
void Vector<T>::remove_keep_order(const int index) {
--_size;
for (int i = index; i < _size; ++i) {
_data[i] = _data[i + 1];
}
}
template <class T>
void Vector<T>::erase(const T &element) {
int index = find(element);