Skip to content

Commit 0d967cf

Browse files
authored
Sync connect (#865)
1 parent 527058c commit 0d967cf

File tree

5 files changed

+96
-162
lines changed

5 files changed

+96
-162
lines changed

exercises/practice/connect/.docs/instructions.md

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,14 @@
22

33
Compute the result for a game of Hex / Polygon.
44

5-
The abstract boardgame known as
6-
[Hex](https://en.wikipedia.org/wiki/Hex_%28board_game%29) / Polygon /
7-
CON-TAC-TIX is quite simple in rules, though complex in practice. Two players
8-
place stones on a parallelogram with hexagonal fields. The player to connect his/her
9-
stones to the opposite side first wins. The four sides of the parallelogram are
10-
divided between the two players (i.e. one player gets assigned a side and the
11-
side directly opposite it and the other player gets assigned the two other
12-
sides).
5+
The abstract boardgame known as [Hex][hex] / Polygon / CON-TAC-TIX is quite simple in rules, though complex in practice.
6+
Two players place stones on a parallelogram with hexagonal fields.
7+
The player to connect his/her stones to the opposite side first wins.
8+
The four sides of the parallelogram are divided between the two players (i.e. one player gets assigned a side and the side directly opposite it and the other player gets assigned the two other sides).
139

14-
Your goal is to build a program that given a simple representation of a board
15-
computes the winner (or lack thereof). Note that all games need not be "fair".
16-
(For example, players may have mismatched piece counts or the game's board might
17-
have a different width and height.)
10+
Your goal is to build a program that given a simple representation of a board computes the winner (or lack thereof).
11+
Note that all games need not be "fair".
12+
(For example, players may have mismatched piece counts or the game's board might have a different width and height.)
1813

1914
The boards look like this:
2015

@@ -26,6 +21,7 @@ The boards look like this:
2621
X O O O X
2722
```
2823

29-
"Player `O`" plays from top to bottom, "Player `X`" plays from left to right. In
30-
the above example `O` has made a connection from left to right but nobody has
31-
won since `O` didn't connect top and bottom.
24+
"Player `O`" plays from top to bottom, "Player `X`" plays from left to right.
25+
In the above example `O` has made a connection from left to right but nobody has won since `O` didn't connect top and bottom.
26+
27+
[hex]: https://en.wikipedia.org/wiki/Hex_%28board_game%29

exercises/practice/connect/.meta/config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,5 @@
2323
".meta/example.php"
2424
]
2525
},
26-
"blurb": "Compute the result for a game of Hex / Polygon"
26+
"blurb": "Compute the result for a game of Hex / Polygon."
2727
}

exercises/practice/connect/.meta/example.php

Lines changed: 6 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,5 @@
11
<?php
22

3-
/*
4-
* By adding type hints and enabling strict type checking, code can become
5-
* easier to read, self-documenting and reduce the number of potential bugs.
6-
* By default, type declarations are non-strict, which means they will attempt
7-
* to change the original type to match the type specified by the
8-
* type-declaration.
9-
*
10-
* In other words, if you pass a string to a function requiring a float,
11-
* it will attempt to convert the string value to a float.
12-
*
13-
* To enable strict mode, a single declare directive must be placed at the top
14-
* of the file.
15-
* This means that the strictness of typing is configured on a per-file basis.
16-
* This directive not only affects the type declarations of parameters, but also
17-
* a function's return type.
18-
*
19-
* For more info review the Concept on strict type checking in the PHP track
20-
* <link>.
21-
*
22-
* To disable strict typing, comment out the directive below.
23-
*/
24-
253
declare(strict_types=1);
264

275
const NOTHING = 0;
@@ -118,40 +96,14 @@ public function blackStartCoords(): array
11896
}
11997
return $coords;
12098
}
121-
122-
// Prints the board, occasionally useful for debugging.
123-
// Capital letters indicate a connect flag has been set.
124-
public function dump(): void
125-
{
126-
print "\n";
127-
for ($y = 0; $y < $this->height; $y++) {
128-
print str_repeat(" ", $y);
129-
for ($x = 0; $x < $this->width; $x++) {
130-
$f = $this->fields[$y][$x];
131-
if ($f & WHITE) {
132-
if ($f & WHITE_CONNECT) {
133-
print "O";
134-
} else {
135-
print "o";
136-
}
137-
} elseif ($f & BLACK) {
138-
if ($f & BLACK_CONNECT) {
139-
print "X";
140-
} else {
141-
print "x";
142-
}
143-
} else {
144-
print ".";
145-
}
146-
print " ";
147-
}
148-
print "\n";
149-
}
150-
}
15199
}
152100

153-
function resultFor(array $lines)
101+
function winner(array $lines): ?string
154102
{
103+
$lines = array_map(function ($line) {
104+
return str_replace(" ", "", $line);
105+
}, $lines);
106+
155107
$board = new Board($lines);
156108
// Order of checking black and white doesn't matter, only one can win.
157109
foreach ($board->blackStartCoords() as $c) {
@@ -167,7 +119,7 @@ function resultFor(array $lines)
167119
return null;
168120
}
169121

170-
function flood($board, $c, $colour_flag, $connect_flag)
122+
function flood($board, $c, $colour_flag, $connect_flag): bool
171123
{
172124
$f = $board->at($c);
173125
$is_colour = $f & $colour_flag;

exercises/practice/connect/Connect.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
declare(strict_types=1);
2626

27-
function resultFor(array $lines)
27+
function winner(array $lines): ?string
2828
{
29-
throw new \BadFunctionCallException("Implement the resultFor method");
29+
throw new \BadFunctionCallException("Implement the winner method");
3030
}
Lines changed: 76 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,5 @@
11
<?php
22

3-
/*
4-
* By adding type hints and enabling strict type checking, code can become
5-
* easier to read, self-documenting and reduce the number of potential bugs.
6-
* By default, type declarations are non-strict, which means they will attempt
7-
* to change the original type to match the type specified by the
8-
* type-declaration.
9-
*
10-
* In other words, if you pass a string to a function requiring a float,
11-
* it will attempt to convert the string value to a float.
12-
*
13-
* To enable strict mode, a single declare directive must be placed at the top
14-
* of the file.
15-
* This means that the strictness of typing is configured on a per-file basis.
16-
* This directive not only affects the type declarations of parameters, but also
17-
* a function's return type.
18-
*
19-
* For more info review the Concept on strict type checking in the PHP track
20-
* <link>.
21-
*
22-
* To disable strict typing, comment out the directive below.
23-
*/
24-
253
declare(strict_types=1);
264

275
class ConnectTest extends PHPUnit\Framework\TestCase
@@ -32,15 +10,9 @@ public static function setUpBeforeClass(): void
3210
}
3311

3412
/**
35-
* Strip off the spaces which are only for readability.
13+
* uuid 6eff0df4-3e92-478d-9b54-d3e8b354db56
14+
* @testdox an empty board has no winner
3615
*/
37-
private function makeBoard($lines): array
38-
{
39-
return array_map(function ($line) {
40-
return str_replace(" ", "", $line);
41-
}, $lines);
42-
}
43-
4416
public function testEmptyBoardHasNoWinner(): void
4517
{
4618
$lines = [
@@ -50,62 +22,81 @@ public function testEmptyBoardHasNoWinner(): void
5022
" . . . . .",
5123
" . . . . .",
5224
];
53-
$this->assertEquals(null, resultFor($this->makeBoard($lines)));
25+
$this->assertEquals(null, winner($lines));
5426
}
5527

5628
/**
57-
* @depends testEmptyBoardHasNoWinner
29+
* uuid 298b94c0-b46d-45d8-b34b-0fa2ea71f0a4
30+
* @testdox X can win on a 1x1 board
5831
*/
5932
public function testOneByOneBoardBlack(): void
6033
{
6134
$lines = ["X"];
62-
$this->assertEquals("black", resultFor($this->makeBoard($lines)));
35+
$this->assertEquals("black", winner($lines));
6336
}
6437

6538
/**
66-
* @depends testEmptyBoardHasNoWinner
39+
* uuid 763bbae0-cb8f-4f28-bc21-5be16a5722dc
40+
* @testdox O can win on a 1x1 board
6741
*/
6842
public function testOneByOneBoardWhite(): void
6943
{
7044
$lines = ["O"];
71-
$this->assertEquals("white", resultFor($this->makeBoard($lines)));
45+
$this->assertEquals("white", winner($lines));
7246
}
7347

7448
/**
75-
* @depends testOneByOneBoardBlack
76-
* @depends testOneByOneBoardWhite
49+
* uuid 819fde60-9ae2-485e-a024-cbb8ea68751b
50+
* @testdox only edges does not make a winner
7751
*/
78-
public function testConvultedPath(): void
52+
public function testOnlyEgesDoesNotMakeAWinner(): void
7953
{
8054
$lines = [
81-
". X X . .",
82-
" X . X . X",
83-
" . X . X .",
84-
" . X X . .",
85-
" O O O O O",
55+
"O O O X",
56+
" X . . X",
57+
" X . . X",
58+
" X O O O",
8659
];
87-
$this->assertEquals("black", resultFor($this->makeBoard($lines)));
60+
$this->assertEquals("", winner($lines));
8861
}
8962

9063
/**
91-
* @depends testConvultedPath
64+
* uuid 2c56a0d5-9528-41e5-b92b-499dfe08506c
65+
* @testdox illegal diagonal does not make a winner
9266
*/
93-
public function testRectangleWhiteWins(): void
67+
public function testIllegalDiagonalDoesNotMakeAWinner(): void
9468
{
9569
$lines = [
96-
". O . .",
70+
"X O . .",
9771
" O X X X",
98-
" O O O .",
99-
" X X O X",
100-
" . O X .",
72+
" O X O .",
73+
" . O X .",
74+
" X X O O",
75+
];
76+
$this->assertEquals("", winner($lines));
77+
}
78+
79+
/**
80+
* uuid 41cce3ef-43ca-4963-970a-c05d39aa1cc1
81+
* @testdox nobody wins crossing adjacent angles
82+
*/
83+
public function testNobodyWinsCrossingAdjacentAngles(): void
84+
{
85+
$lines = [
86+
"X . . .",
87+
" . X O .",
88+
" O . X O",
89+
" . O . X",
90+
" . . O .",
10191
];
102-
$this->assertEquals("white", resultFor($this->makeBoard($lines)));
92+
$this->assertEquals("", winner($lines));
10393
}
10494

10595
/**
106-
* @depends testConvultedPath
96+
* uuid cd61c143-92f6-4a8d-84d9-cb2b359e226b
97+
* @testdox X wins crossing from left to right
10798
*/
108-
public function testRectangleBlackWins(): void
99+
public function testXWinsCrossingFromLeftToRight(): void
109100
{
110101
$lines = [
111102
". O . .",
@@ -114,63 +105,58 @@ public function testRectangleBlackWins(): void
114105
" X X O X",
115106
" . O X .",
116107
];
117-
$this->assertEquals("black", resultFor($this->makeBoard($lines)));
108+
$this->assertEquals("black", winner($lines));
118109
}
119110

120111
/**
121-
* @depends testRectangleWhiteWins
122-
* @depends testRectangleBlackWins
112+
* uuid 73d1eda6-16ab-4460-9904-b5f5dd401d0b
113+
* @testdox O wins crossing from top to bottom
123114
*/
124-
public function testSpiralBlackWins(): void
115+
public function testOWinsCrossingFromTopToBottom(): void
125116
{
126117
$lines = [
127-
"OXXXXXXXX",
128-
"OXOOOOOOO",
129-
"OXOXXXXXO",
130-
"OXOXOOOXO",
131-
"OXOXXXOXO",
132-
"OXOOOXOXO",
133-
"OXXXXXOXO",
134-
"OOOOOOOXO",
135-
"XXXXXXXXO",
118+
". O . .",
119+
" O X X X",
120+
" O O O .",
121+
" X X O X",
122+
" . O X .",
136123
];
137-
$this->assertEquals("black", resultFor($this->makeBoard($lines)));
124+
$this->assertEquals("white", winner($lines));
138125
}
139126

140127
/**
141-
* @depends testRectangleWhiteWins
142-
* @depends testRectangleBlackWins
128+
* uuid c3a2a550-944a-4637-8b3f-1e1bf1340a3d
129+
* @testdox X wins using a convoluted path
143130
*/
144-
public function testSpiralNobodyWins(): void
131+
public function testXWinsUsingAConvolutedPath(): void
145132
{
146133
$lines = [
147-
"OXXXXXXXX",
148-
"OXOOOOOOO",
149-
"OXOXXXXXO",
150-
"OXOXOOOXO",
151-
"OXOX.XOXO",
152-
"OXOOOXOXO",
153-
"OXXXXXOXO",
154-
"OOOOOOOXO",
155-
"XXXXXXXXO",
134+
". X X . .",
135+
" X . X . X",
136+
" . X . X .",
137+
" . X X . .",
138+
" O O O O O",
156139
];
157-
$this->assertEquals(null, resultFor($this->makeBoard($lines)));
140+
$this->assertEquals("black", winner($lines));
158141
}
159142

160143
/**
161-
* @depends testSpiralBlackWins
162-
* @depends testSpiralNobodyWins
144+
* uuid 17e76fa8-f731-4db7-92ad-ed2a285d31f3
145+
* @testdox X wins using a spiral path
163146
*/
164-
public function testIllegalDiagonalNobodyWins(): void
147+
public function testXWinsUsingASpiralPath(): void
165148
{
166149
$lines = [
167-
"X O . .",
168-
" O X X X",
169-
" O X O .",
170-
" . O X .",
171-
" X X O O",
150+
"O X X X X X X X X",
151+
" O X O O O O O O O",
152+
" O X O X X X X X O",
153+
" O X O X O O O X O",
154+
" O X O X X X O X O",
155+
" O X O O O X O X O",
156+
" O X X X X X O X O",
157+
" O O O O O O O X O",
158+
" X X X X X X X X O",
172159
];
173-
174-
$this->assertEquals(null, resultFor($this->makeBoard($lines)));
160+
$this->assertEquals("black", winner($lines));
175161
}
176162
}

0 commit comments

Comments
 (0)