aboutsummaryrefslogtreecommitdiff
path: root/draughts/piece.js
blob: e0885fb442a225ab422309c4064c719d4140b09a (plain) (blame)
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
const Color = require("./public/javascripts/color")

/*
 * Signature:
 *     (Piece) => Number[2][]
 *
 * Description:
 *     Return all of the possible non-capturing moves that the piece `p' could theoretically make
 *     assuming that it is not a king piece. The moves are represented as arrays of 2 numbers, an `x'
 *     and a `y' position.
 */
const nonCapturingMovesStandard =
	  p => p.color == Color.BLUE
	  ? [[p.position.x + 1, p.position.y + 1],
		 [p.position.x - 1, p.position.y + 1]]
	  : [[p.position.x + 1, p.position.y - 1],
		 [p.position.x - 1, p.position.y - 1]]

/*
 * Signature:
 *     (Piece) => Number[2][]
 *
 * Description:
 *     The same as above except we assume that `p' is a king piece.
 */
const nonCapturingMovesKing =
	  p => [1, 2, 3, 4, 5, 6, 7, 8, 9].map(n => [[n, n], [n, -n], [-n, n], [-n, -n]])
									  .flat()
									  .map(([x, y]) => [p.position.x + x, p.position.y + y])

/*
 * Signature:
 *     (Piece) => { skipped: { x: Number, y: Number }, landed: { x: Number, y: Number } }[]
 *
 * Description:
 *     Return all of the possible capturing moves that the piece `p' could theoretically make
 *     assuming that it is not a king piece. The moves are represented as objects with a `skipped'
 *     and a `landed' attribute. The `skipped' attribute represents the location on the board that
 *     the piece skipped over in the capture, and the `landed' attribute is where the piece actually
 *     landed.
 */
const capturingMovesStandard = p => [
	{ skipped: { x: p.position.x + 1, y: p.position.y + 1 },
	  landed:  { x: p.position.x + 2, y: p.position.y + 2 } },
	{ skipped: { x: p.position.x - 1, y: p.position.y + 1 },
	  landed:  { x: p.position.x - 2, y: p.position.y + 2 } },
	{ skipped: { x: p.position.x + 1, y: p.position.y - 1 },
	  landed:  { x: p.position.x + 2, y: p.position.y - 2 } },
	{ skipped: { x: p.position.x - 1, y: p.position.y - 1 },
	  landed:  { x: p.position.x - 2, y: p.position.y - 2 } }
]

/*
 * Signature:
 *     (Piece) => { skipped: { x: Number, y: Number }, landed: { x: Number, y: Number } }[]
 *
 * Description:
 *     The same as above except we assume that `p' is a king piece.
 */
const capturingMovesKing =
	  p => [1, 2, 3, 4, 5, 6, 7, 8].map(
		  n => [{ skipped: { x: p.position.x + n,     y: p.position.y + n     },
				  landed:  { x: p.position.x + n + 1, y: p.position.y + n + 1 } },
				{ skipped: { x: p.position.x + n,     y: p.position.y - n     },
				  landed:  { x: p.position.x + n + 1, y: p.position.y - n - 1 } },
				{ skipped: { x: p.position.x - n,     y: p.position.y + n     },
				  landed:  { x: p.position.x - n - 1, y: p.position.y + n + 1 } },
				{ skipped: { x: p.position.x - n,     y: p.position.y - n     },
				  landed:  { x: p.position.x - n - 1, y: p.position.y - n - 1 } }
			   ]).flat()

/*
 * Signature:
 *     this.position :: { x: Number, y: Number }
 *     this.id       :: Number
 *     this.color    :: Color
 *     this.isKing   :: Boolean
 *
 * Description:
 *     A class representing a draughts piece. It has a position within the board as well as an ID
 *     that corresponds to its ID in the HTML DOM, a color, and a boolean that determines if it's a
 *     king or not.
 */
const Piece = function(x, y, id, color) {
	this.position = {
		x: x,
		y: y
	}
	this.id = id
	this.color = color
	this.isKing = false
}

/*
 * Signature:
 *     () => Number[2][]
 *
 * Description:
 *     Return an array of coordinates (each coordinate is an array with an `x' and `y' value) for all
 *     of the possible moves that the piece `this' could theoretically make in any given scenario
 *     which do *not* capture any pieces.
 */
Piece.prototype.nonCapturingMoves = function() {
	return this.isKing ? nonCapturingMovesKing(this) : nonCapturingMovesStandard(this)
}

/*
 * Signature:
 *     () => { skipped: { x: Number, y: Number }, landed: { x: Number, y: Number } }[]
 *
 * Description:
 *     This is the same as the above function but returns the moves which *do* capture pieces. The
 *     output is just an array of moves in the format described by the `capturingMovesKing()' and
 *     `capturingMovesStandard()' functions.
 */
Piece.prototype.capturingMoves = function() {
	return this.isKing ? capturingMovesKing(this) : capturingMovesStandard(this)
}

/*
 * Signature:
 *     (Piece) => Boolean
 *
 * Description:
 *     Return `true' or `false' depending on if `this' and `other' are on the same team or not.
 */
Piece.prototype.sameTeam = function(other) {
	return this.color == other.color
}

module.exports = Piece