summaryrefslogtreecommitdiff
path: root/board.h
blob: 6b17d537164366cd47d84f65c8cc96506e7d4b1e (plain)
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
#pragma once

#include <iostream>
#include <vector>
#include "move.h"

using namespace std;


const int WHITE = 0;
const int BLACK = 1;

const int EMPTY = 0, PAWN = 1, ROOK = 2, KNIGHT = 3, BISHOP = 4, KING = 5, QUEEN = 6;

// BLACK BLACK BLACK  y = 0
// ...
// ...
// WHITE WHITE WHITE  y = 7

enum class CheckResult {
	safe, check, checkmate, stalemate
};


#define IDX(x_, y_) (8 * (y_) + (x_))


class Board {
	int bd[64];  // 0 = empty, >0 = white, <0 = black

public:
	int pieceScore[2];  // captured points by player
	int lastTarget;  // destination of last move
	int onTurn;  // colour of player to move
	bool kingMoved[2], rookLmoved[2], rookRmoved[2];

	Board();

	template <typename F>  // void(Board&)
	inline Board newWith(const F &func) const {
		Board B(*this);
		func(B);
		return B;
	}

	inline int& at(int x, int y) {return at(IDX(x, y));}
	inline int& at(int idx) {return bd[idx];}
	inline int at(int x, int y) const {return at(IDX(x, y));}
	inline int at(int idx) const {return bd[idx];}

	int locate(int stone) const;  // moderately slow (iterates board)

	static inline int colour(int stone) {return stone > 0 ? WHITE : BLACK;}

	static inline int worth(int stone) {
		static const int w[7] = {0, 1, 5, 3, 3, 100000000, 9};
		return w[abs(stone)];
	}

	vector<Board> subsequents() const;

	void apply(const Move &mv);  // does not perform checking

	bool isValid(const Move &mv) const;  // SLOW

	// SLOW; Only detects anything for the given player.
	// Assumes no king has been taken yet.
	CheckResult checkCheck(int player) const;

	friend bool operator==(const Board &B1, const Board &B2);
};

ostream& operator<<(ostream &os, const Board &B);
bool operator==(const Board &B1, const Board &B2);