Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save constructor-s/cad23e715e8b7e223801a4c99139fed5 to your computer and use it in GitHub Desktop.

Select an option

Save constructor-s/cad23e715e8b7e223801a4c99139fed5 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Gomoku Project - Complete Test Suite</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
line-height: 1.6;
color: #333;
max-width: 1000px;
margin: 0 auto;
padding: 20px;
background-color: #f9f9f9;
}
header {
border-bottom: 2px solid #0056b3;
margin-bottom: 30px;
padding-bottom: 10px;
}
h1 {
color: #0056b3;
margin-bottom: 5px;
}
.instructions {
background-color: #e9ecef;
padding: 15px;
border-radius: 5px;
margin-bottom: 25px;
border-left: 5px solid #0056b3;
}
details {
background-color: #fff;
border: 1px solid #ddd;
border-radius: 5px;
margin-bottom: 15px;
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
overflow: hidden;
}
summary {
padding: 15px;
background-color: #f1f3f5;
cursor: pointer;
font-weight: bold;
font-family: monospace;
font-size: 1.1em;
display: flex;
justify-content: space-between;
align-items: center;
}
summary:hover {
background-color: #e2e6ea;
}
.code-wrapper {
position: relative;
background-color: #282c34;
}
pre {
margin: 0;
padding: 20px;
overflow-x: auto;
color: #abb2bf;
font-family: 'Consolas', 'Monaco', 'Andale Mono', monospace;
font-size: 14px;
line-height: 1.5;
}
.copy-btn {
position: absolute;
top: 10px;
right: 10px;
background-color: rgba(255, 255, 255, 0.1);
color: #fff;
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 4px;
padding: 5px 10px;
font-size: 12px;
cursor: pointer;
transition: all 0.2s;
}
.copy-btn:hover {
background-color: rgba(255, 255, 255, 0.2);
}
.test-description {
padding: 15px 20px 0 20px;
font-style: italic;
color: #666;
font-size: 0.9em;
}
</style>
</head>
<body>
<header>
<h1>Gomoku Project Test Suite</h1>
<p>ESC 180 - Fall 2025</p>
</header>
<div class="instructions">
<strong>How to use these tests:</strong>
<ol>
<li>Expand a test file section below.</li>
<li>Click the "Copy" button.</li>
<li>Create a new file in your project folder (where <code>gomoku.py</code> is located, so it can be imported) with the filename shown in the header (e.g., <code>test_detect_row_student.py</code>).</li>
<li>Paste the code and save.</li>
<li>Run the file using Pyzo or the command line (e.g., <code>python3 test_detect_row_student.py</code>).</li>
</ol>
</div>
<!-- TEST 1: detect_row -->
<details>
<summary>test_detect_row_student.py</summary>
<div class="test-description">
Tests for the <code>detect_row</code> function. Covers basic open sequences, bound sequences, semi-open sequences, and edge cases.
</div>
<div class="code-wrapper">
<button class="copy-btn" onclick="copyCode(this)">Copy</button>
<pre><code>"""
TestDetectRow Student Test Suite
Test Cases:
1. test_len2_unbound_x
2. test_len2_unbound_y_white
3. test_len2_unbound_y
4. test_len3_unbound_y_constrained
5. test_len4_unbound_d_constrained
6. test_len2_unbound_rd
7. test_len2_bound_y
8. test_len2_bound_x
9. test_len3_bound_x_boarder
10. test_len4_bound_d_boarder
11. test_len4_bound_d_boarder_lower_right_white
12. test_len2_bound_rd
13. test_len3_bound_rd_boundry
14. test_len2_semi_y
15. test_len2_semi_rd
16. test_len2_semi_x
17. test_len3_semi_x_boarder
18. test_len4_semi_d_boarder
19. test_len4_semi_d_boarder_lower_right_white
"""
import gomoku
def test_len2_unbound_x():
"""Test Case 1: Length 2 open sequence in x direction (black)"""
board = [[' ',' ',' ',' ',' ',' ',' ',' '],
[' ','b','b',' ','w',' ',' ',' '],
[' ',' ',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.detect_row(board,'b',1, 0, 2, 0, 1)
expected = (1,0)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len2_unbound_x PASSED")
def test_len2_unbound_y_white():
"""Test Case 2: Length 2 open sequence in y direction (white)"""
board = [[' ',' ',' ',' ',' ',' ',' ',' '],
[' ','b','b',' ','w',' ',' ',' '],
[' ',' ',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.detect_row(board,'w',0, 4, 2, 1, 0)
expected = (1,0)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len2_unbound_y_white PASSED")
def test_len2_unbound_y():
"""Test Case 3: Length 2 open sequence in y direction (black)"""
board = [[' ',' ',' ',' ',' ',' ',' ',' '],
[' ','b','b',' ','w',' ',' ',' '],
[' ','b',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.detect_row(board,'b',0, 1, 2, 1, 0)
expected = (1,0)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len2_unbound_y PASSED")
def test_len3_unbound_y_constrained():
"""Test Case 4: Length 3 open sequence in y direction with surrounding stones"""
board = [[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ','b','b','b',' ',' ',' '],
[' ',' ','b','b','w','w','w',' '],
[' ',' ','b','w','b',' ',' ',' '],
[' ',' ',' ','w',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ','w',' '],
[' ',' ',' ',' ',' ',' ','w',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.detect_row(board,'b',0, 2, 3, 1, 0)
expected = (1,0)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len3_unbound_y_constrained PASSED")
def test_len4_unbound_d_constrained():
"""Test Case 5: Length 4 open sequence in diagonal (1,1) direction"""
board = [[' ','w',' ',' ',' ',' ',' ',' '],
['w','b','b',' ','w',' ',' ',' '],
[' ','b','b',' ','w',' ',' ',' '],
[' ',' ',' ','b','w',' ',' ',' '],
['b',' ',' ',' ','b','w',' ',' '],
[' ',' ',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.detect_row(board,'b',0, 0, 4, 1, 1)
expected = (1,0)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len4_unbound_d_constrained PASSED")
def test_len2_unbound_rd():
"""Test Case 6: Length 2 open sequence in reverse diagonal (1,-1) direction"""
board = [[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ','b','w',' ',' ',' ',' '],
[' ','b','w','b',' ',' ',' ',' '],
[' ','w',' ',' ',' ',' ',' ',' '],
['w','b',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.detect_row(board,'b',0, 3, 2, 1, -1)
expected = (1,0)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len2_unbound_rd PASSED")
def test_len2_bound_y():
"""Test Case 7: Length 2 closed sequence in y direction"""
board = [[' ','w',' ',' ',' ',' ',' ',' '],
[' ','b','b',' ',' ',' ',' ',' '],
['b','b',' ',' ',' ',' ',' ',' '],
[' ','w',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.detect_row(board,'b',0, 1, 2, 1, 0)
expected = (0,0)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len2_bound_y PASSED")
def test_len2_bound_x():
"""Test Case 8: Length 2 closed sequence in x direction"""
board = [[' ',' ',' ',' ',' ',' ',' ',' '],
['w','b','b','w',' ',' ',' ',' '],
[' ','b',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.detect_row(board,'b',1, 0, 2, 0, 1)
expected = (0,0)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len2_bound_x PASSED")
def test_len3_bound_x_boarder():
"""Test Case 9: Length 3 closed sequence in x direction (border)"""
board = [[' ',' ',' ',' ',' ',' ',' ',' '],
['b','b','b','w',' ',' ',' ',' '],
['w','b',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.detect_row(board,'b',1, 0, 3, 0, 1)
expected = (0,0)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len3_bound_x_boarder PASSED")
def test_len4_bound_d_boarder():
"""Test Case 10: Length 4 closed sequence in diagonal direction (border)"""
board = [['b','b','b','b',' ',' ',' ',' '],
['w','b','b',' ','w',' ',' ',' '],
[' ',' ','b',' ',' ',' ',' ',' '],
[' ',' ',' ','b',' ',' ',' ',' '],
[' ',' ',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ',' ','w',' ',' '],
[' ',' ',' ',' ',' ',' ','w',' '],
['w','w','w',' ',' ',' ',' ',' ']]
result = gomoku.detect_row(board,'b',0, 0, 4, 1, 1)
expected = (0,0)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len4_bound_d_boarder PASSED")
def test_len4_bound_d_boarder_lower_right_white():
"""Test Case 11: Length 4 closed sequence in diagonal direction (black stones)"""
board = [['b',' ','b','b',' ','b',' ',' '],
[' ',' ',' ','b','b',' ',' ',' '],
[' ','b',' ','w',' ',' ',' ',' '],
[' ',' ',' ','b',' ','b',' ',' '],
[' ','b','b',' ','w','w','w','w'],
[' ',' ',' ','b','w','w',' ',' '],
[' ',' ',' ','b','w',' ','w',' '],
['w','w','b','w','w',' ',' ','w']]
result = gomoku.detect_row(board,'b',0, 0, 4, 1, 1)
expected = (0,0)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len4_bound_d_boarder_lower_right_white PASSED")
def test_len2_bound_rd():
"""Test Case 12: Length 2 closed sequence in reverse diagonal direction"""
board = [[' ',' ',' ','w',' ',' ',' ',' '],
[' ','b','b',' ',' ',' ',' ',' '],
[' ','b','w',' ',' ',' ',' ',' '],
['w','w',' ',' ',' ',' ',' ',' '],
[' ','b',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.detect_row(board,'b',0, 3, 2, 1, -1)
expected = (0,0)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len2_bound_rd PASSED")
def test_len3_bound_rd_boundry():
"""Test Case 13: Length 3 closed sequence in reverse diagonal direction (boundary)"""
board = [[' ',' ',' ','b','w',' ',' ',' '],
[' ',' ','b',' ','b',' ',' ',' '],
[' ','b','w',' ',' ',' ',' ',' '],
['w','w',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.detect_row(board,'b',0, 3, 3, 1, -1)
expected = (0,0)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len3_bound_rd_boundry PASSED")
def test_len2_semi_y():
"""Test Case 14: Length 2 semi-open sequence in y direction"""
board = [[' ','w',' ',' ',' ',' ',' ',' '],
[' ','b','b',' ',' ',' ',' ',' '],
['b','b','w',' ',' ',' ',' ',' '],
[' ',' ',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.detect_row(board,'b',0, 1, 2, 1, 0)
expected = (0,1)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len2_semi_y PASSED")
def test_len2_semi_rd():
"""Test Case 15: Length 2 semi-open sequence in reverse diagonal direction"""
board = [[' ','w',' ',' ',' ',' ',' ',' '],
[' ',' ','b','b',' ',' ',' ',' '],
[' ','b','w',' ',' ',' ',' ',' '],
['w','w',' ',' ',' ',' ',' ',' '],
[' ','b',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.detect_row(board,'b',0, 3, 2, 1, -1)
expected = (0,1)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len2_semi_rd PASSED")
def test_len2_semi_x():
"""Test Case 16: Length 2 semi-open sequence in x direction"""
board = [[' ',' ','b',' ',' ',' ',' ',' '],
['w','b','b',' ',' ',' ',' ',' '],
[' ',' ','w',' ',' ',' ',' ',' '],
[' ',' ',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.detect_row(board,'b',1, 0, 2, 0, 1)
expected = (0,1)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len2_semi_x PASSED")
def test_len3_semi_x_boarder():
"""Test Case 17: Length 3 semi-open sequence in x direction (border)"""
board = [['b',' ','b',' ',' ',' ',' ',' '],
['w','b','b','w','w',' ',' ',' '],
['b','b','b',' ',' ',' ',' ',' '],
[' ',' ','w','w','w',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.detect_row(board,'b',2, 0, 3, 0, 1)
expected = (0,1)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len3_semi_x_boarder PASSED")
def test_len4_semi_d_boarder():
"""Test Case 18: Length 4 semi-open sequence in diagonal direction (border)"""
board = [['b',' ',' ','b',' ',' ',' ',' '],
['w','b','b','b','w',' ',' ',' '],
[' ',' ','b','b',' ',' ',' ',' '],
['b','b','b','b','w',' ',' ',' '],
[' ',' ',' ','w',' ',' ',' ',' '],
[' ',' ',' ','w',' ','w',' ',' '],
[' ',' ',' ','w',' ',' ','w',' '],
['w','w','w','w',' ',' ',' ',' ']]
result = gomoku.detect_row(board,'b',0, 0, 4, 1, 1)
expected = (0,1)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len4_semi_d_boarder PASSED")
def test_len4_semi_d_boarder_lower_right_white():
"""Test Case 19: Length 4 semi-open sequence in diagonal direction (white stones)"""
board = [['b',' ','b','b',' ',' ',' ',' '],
[' ',' ',' ','b','b',' ',' ',' '],
[' ',' ',' ','b',' ',' ',' ',' '],
[' ',' ',' ',' ','b',' ',' ',' '],
[' ',' ',' ','b','w','w','w','w'],
[' ',' ',' ','b','w','w',' ',' '],
[' ',' ',' ','b','w',' ','w',' '],
['w','w','b','b','w',' ',' ','w']]
result = gomoku.detect_row(board,'w',0, 0, 4, 1, 1)
expected = (0,1)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len4_semi_d_boarder_lower_right_white PASSED")
if __name__ == '__main__':
test_len2_unbound_x()
test_len2_unbound_y_white()
test_len2_unbound_y()
test_len3_unbound_y_constrained()
test_len4_unbound_d_constrained()
test_len2_unbound_rd()
test_len2_bound_y()
test_len2_bound_x()
test_len3_bound_x_boarder()
test_len4_bound_d_boarder()
test_len4_bound_d_boarder_lower_right_white()
test_len2_bound_rd()
test_len3_bound_rd_boundry()
test_len2_semi_y()
test_len2_semi_rd()
test_len2_semi_x()
test_len3_semi_x_boarder()
test_len4_semi_d_boarder()
test_len4_semi_d_boarder_lower_right_white()
print("All tests passed for test_detect_row_student.py!")
</code></pre>
</div>
</details>
<!-- TEST 2: detect_rows -->
<details>
<summary>test_detect_rows_student.py</summary>
<div class="test-description">
Tests for the <code>detect_rows</code> function. Checks aggregation of rows across the whole board.
</div>
<div class="code-wrapper">
<button class="copy-btn" onclick="copyCode(this)">Copy</button>
<pre><code>"""
TestDetectRows Student Test Suite
Test Cases:
1. test_len2_single_unbound_x
2. test_len2_multiple1_unbound_x
3. test_len2_multiple2_unbound_x
4. test_len2_single_unbound_y_white
5. test_len2_unbound_multi_dir2
6. test_unbound_y_include_bound
7. test_unbound_multi_dir_include_bound
8. test_len2_unbound_d_include_semi
9. test_len2_board_boundry
10. test_len2_only_semi_board_boundry_bouind
11. test_len2_only_semi
"""
import gomoku
def test_len2_single_unbound_x():
"""Test Case 1: Single length 2 open sequence in x direction"""
board = [[' ',' ',' ',' ',' ',' ',' ',' '],
[' ','b','b',' ','w',' ',' ',' '],
[' ',' ',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.detect_rows(board,'b', 2)
expected = (1,0)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len2_single_unbound_x PASSED")
def test_len2_multiple1_unbound_x():
"""Test Case 2: Multiple sequences, count only specific length (2)"""
board = [[' ',' ',' ',' ',' ',' ',' ',' '],
[' ','b','b',' ','w','w','w',' '],
[' ',' ',' ',' ','w','w','w',' '],
[' ','b','b','b',' ','w','w',' '],
[' ',' ',' ',' ',' ',' ','w',' '],
[' ','b','b','b','b',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.detect_rows(board,'b', 2)
expected = (1,0)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len2_multiple1_unbound_x PASSED")
def test_len2_multiple2_unbound_x():
"""Test Case 3: Multiple length 2 open sequences"""
board = [[' ',' ',' ',' ',' ',' ',' ',' '],
[' ','b','b',' ','w','w','w',' '],
[' ',' ',' ',' ','w','w','w',' '],
[' ','b','b',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ','b','b',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.detect_rows(board,'b', 2)
expected = (3,0)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len2_multiple2_unbound_x PASSED")
def test_len2_single_unbound_y_white():
"""Test Case 4: Single length 2 open sequence in y direction (white)"""
board = [[' ',' ',' ',' ',' ',' ',' ',' '],
[' ','b','b',' ','w',' ',' ',' '],
[' ',' ',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.detect_rows(board,'w', 2)
expected = (1,0)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len2_single_unbound_y_white PASSED")
def test_len2_unbound_multi_dir2():
"""Test Case 5: Length 2 open sequences in multiple directions"""
board = [[' ',' ',' ',' ',' ',' ',' ',' '],
[' ','b','b',' ','w',' ',' ',' '],
[' ','b',' ',' ','w',' ',' ',' '],
[' ',' ','b',' ','w',' ',' ',' '],
[' ',' ',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.detect_rows(board,'b', 2)
expected = (4,0)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len2_unbound_multi_dir2 PASSED")
def test_unbound_y_include_bound():
"""Test Case 6: Open sequences vs closed sequences (y direction)"""
board = [[' ',' ',' ','w',' ',' ',' ',' '],
[' ','b',' ','b','w',' ',' ',' '],
[' ','b',' ','b','w',' ',' ',' '],
[' ','b',' ','b','w',' ',' ',' '],
[' ',' ',' ','w',' ',' ',' ',' '],
[' ',' ',' ','w',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.detect_rows(board,'b', 3)
expected = (1,0)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_unbound_y_include_bound PASSED")
def test_unbound_multi_dir_include_bound():
"""Test Case 7: Open sequences vs closed sequences (multiple directions)"""
board = [[' ',' ',' ','w',' ',' ',' ',' '],
[' ','w','b','b','b','w',' ',' '],
[' ',' ','b','b','w','w','w',' '],
[' ',' ','b','b','b',' ',' ',' '],
[' ',' ',' ','w',' ',' ',' ',' '],
[' ',' ',' ','w',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.detect_rows(board,'b', 3)
expected = (4,0)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_unbound_multi_dir_include_bound PASSED")
def test_len2_unbound_d_include_semi():
"""Test Case 8: Open and semi-open sequences (diagonal)"""
board = [[' ','w',' ',' ',' ',' ',' ',' '],
['w','b','b',' ','w',' ',' ',' '],
[' ','b','b',' ','w',' ',' ',' '],
[' ',' ',' ','b','w',' ',' ',' '],
['b',' ',' ',' ','b','w',' ',' '],
[' ',' ',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.detect_rows(board,'b', 2)
expected = (3,2)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len2_unbound_d_include_semi PASSED")
def test_len2_board_boundry():
"""Test Case 9: Open and semi-open sequences at board boundary"""
board = [[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ','b','w',' ',' ',' ',' '],
['b','b','w',' ',' ',' ',' ',' '],
[' ','w','w',' ','w',' ',' ',' '],
['b','b',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.detect_rows(board,'b',2)
expected = (1,1)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len2_board_boundry PASSED")
def test_len2_only_semi_board_boundry_bouind():
"""Test Case 10: Only semi-open sequences (blocked by stones and boundary)"""
board = [[' ','w','w','w','b',' ',' ',' '],
['w','b','b',' ',' ',' ',' ',' '],
['b','b',' ',' ',' ',' ',' ',' '],
[' ','w',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.detect_rows(board,'b', 2)
expected = (0,3)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len2_only_semi_board_boundry_bouind PASSED")
def test_len2_only_semi():
"""Test Case 11: Only semi-open sequences"""
board = [[' ','w',' ','w',' ',' ',' ',' '],
[' ','b','b','w',' ',' ',' ',' '],
[' ','b',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.detect_rows(board,'b', 2)
expected = (0,3)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len2_only_semi PASSED")
if __name__ == '__main__':
test_len2_single_unbound_x()
test_len2_multiple1_unbound_x()
test_len2_multiple2_unbound_x()
test_len2_single_unbound_y_white()
test_len2_unbound_multi_dir2()
test_unbound_y_include_bound()
test_unbound_multi_dir_include_bound()
test_len2_unbound_d_include_semi()
test_len2_board_boundry()
test_len2_only_semi_board_boundry_bouind()
test_len2_only_semi()
print("All tests passed for test_detect_rows_student.py!")
</code></pre>
</div>
</details>
<!-- TEST 3: hidden -->
<details>
<summary>test_hidden_student.py</summary>
<div class="test-description">
Comprehensive tests covering complex board states and edge cases previously used as hidden grading tests.
</div>
<div class="code-wrapper">
<button class="copy-btn" onclick="copyCode(this)">Copy</button>
<pre><code>"""
TestHidden Student Test Suite
This file contains additional comprehensive test cases that verify:
1. detect_rows on complex board states for specific lengths.
2. search_max logic on specific board configurations.
Test Cases:
1. test_detect_rows_complex_1_black
2. test_detect_rows_complex_1_white
3. test_detect_rows_complex_2_black
4. test_detect_rows_complex_2_white
5. test_detect_rows_complex_3_black
6. test_detect_rows_complex_3_white
7. test_search_max_complex_1
8. test_search_max_complex_2
"""
import gomoku
def test_detect_rows_complex_1_black():
"""Test Case 1: Complex board 1, Player Black"""
board = [[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
[' ', ' ', 'w', ' ', ' ', 'b', ' ', ' '],
[' ', ' ', ' ', 'w', 'b', ' ', ' ', ' '],
[' ', ' ', ' ', 'b', ' ', ' ', ' ', ' '],
[' ', ' ', 'w', ' ', ' ', ' ', ' ', ' '],
[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']]
player = 'b'
expected = {
2 : (0, 0) ,
3 : (0, 1) ,
4 : (0, 0) ,
5 : (0, 0) ,
}
print("\nRunning test_detect_rows_complex_1_black...")
gomoku.print_board(board)
for length, exp_val in expected.items():
result = gomoku.detect_rows(board, player, length)
assert result == exp_val, f"Length {length}: Expected {exp_val}, got {result}"
print("PASSED")
def test_detect_rows_complex_1_white():
"""Test Case 2: Complex board 1, Player White"""
board = [[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
[' ', ' ', 'w', ' ', ' ', 'b', ' ', ' '],
[' ', ' ', ' ', 'w', 'b', ' ', ' ', ' '],
[' ', ' ', ' ', 'b', ' ', ' ', ' ', ' '],
[' ', ' ', 'w', ' ', ' ', ' ', ' ', ' '],
[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']]
player = 'w'
expected = {
2 : (1, 0) ,
3 : (0, 0) ,
4 : (0, 0) ,
5 : (0, 0) ,
}
print("\nRunning test_detect_rows_complex_1_white...")
# Board is same as above, skipping print to reduce noise
for length, exp_val in expected.items():
result = gomoku.detect_rows(board, player, length)
assert result == exp_val, f"Length {length}: Expected {exp_val}, got {result}"
print("PASSED")
def test_detect_rows_complex_2_black():
"""Test Case 3: Complex board 2, Player Black"""
board = [['w', 'b', ' ', ' ', ' ', ' ', 'w', ' '],
['w', ' ', ' ', 'w', ' ', ' ', ' ', ' '],
[' ', ' ', ' ', ' ', ' ', ' ', 'b', 'w'],
[' ', ' ', ' ', ' ', ' ', ' ', ' ', 'b'],
['b', ' ', 'b', ' ', ' ', ' ', ' ', ' '],
[' ', ' ', ' ', ' ', 'b', ' ', 'w', ' '],
['b', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
[' ', ' ', ' ', 'w', 'w', ' ', ' ', ' ']]
player = 'b'
expected = {
2 : (0, 1) ,
3 : (0, 0) ,
4 : (0, 0) ,
5 : (0, 0) ,
}
print("\nRunning test_detect_rows_complex_2_black...")
gomoku.print_board(board)
for length, exp_val in expected.items():
result = gomoku.detect_rows(board, player, length)
assert result == exp_val, f"Length {length}: Expected {exp_val}, got {result}"
print("PASSED")
def test_detect_rows_complex_2_white():
"""Test Case 4: Complex board 2, Player White"""
board = [['w', 'b', ' ', ' ', ' ', ' ', 'w', ' '],
['w', ' ', ' ', 'w', ' ', ' ', ' ', ' '],
[' ', ' ', ' ', ' ', ' ', ' ', 'b', 'w'],
[' ', ' ', ' ', ' ', ' ', ' ', ' ', 'b'],
['b', ' ', 'b', ' ', ' ', ' ', ' ', ' '],
[' ', ' ', ' ', ' ', 'b', ' ', 'w', ' '],
['b', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
[' ', ' ', ' ', 'w', 'w', ' ', ' ', ' ']]
player = 'w'
expected = {
2 : (1, 1) ,
3 : (0, 0) ,
4 : (0, 0) ,
5 : (0, 0) ,
}
print("\nRunning test_detect_rows_complex_2_white...")
for length, exp_val in expected.items():
result = gomoku.detect_rows(board, player, length)
assert result == exp_val, f"Length {length}: Expected {exp_val}, got {result}"
print("PASSED")
def test_detect_rows_complex_3_black():
"""Test Case 5: Complex board 3, Player Black"""
board = [['w', ' ', 'b', 'w', ' ', 'w', ' ', 'b'],
['w', ' ', 'w', 'w', 'b', 'w', 'w', 'b'],
['b', 'b', ' ', 'b', ' ', ' ', 'b', 'w'],
[' ', 'b', 'w', ' ', 'w', 'b', 'b', 'b'],
['b', 'b', 'w', 'b', 'w', 'b', ' ', 'w'],
['w', 'w', 'w', 'w', ' ', 'w', ' ', ' '],
[' ', 'b', 'w', 'b', 'w', ' ', 'w', 'w'],
[' ', ' ', 'w', 'b', ' ', 'b', 'w', 'w']]
player = 'b'
expected = {
2 : (0, 5) ,
3 : (0, 1) ,
4 : (0, 0) ,
5 : (0, 0) ,
}
print("\nRunning test_detect_rows_complex_3_black...")
gomoku.print_board(board)
for length, exp_val in expected.items():
result = gomoku.detect_rows(board, player, length)
assert result == exp_val, f"Length {length}: Expected {exp_val}, got {result}"
print("PASSED")
def test_detect_rows_complex_3_white():
"""Test Case 6: Complex board 3, Player White"""
board = [['w', ' ', 'b', 'w', ' ', 'w', ' ', 'b'],
['w', ' ', 'w', 'w', 'b', 'w', 'w', 'b'],
['b', 'b', ' ', 'b', ' ', ' ', 'b', 'w'],
[' ', 'b', 'w', ' ', 'w', 'b', 'b', 'b'],
['b', 'b', 'w', 'b', 'w', 'b', ' ', 'w'],
['w', 'w', 'w', 'w', ' ', 'w', ' ', ' '],
[' ', 'b', 'w', 'b', 'w', ' ', 'w', 'w'],
[' ', ' ', 'w', 'b', ' ', 'b', 'w', 'w']]
player = 'w'
expected = {
2 : (2, 6) ,
3 : (0, 1) ,
4 : (0, 2) ,
5 : (0, 1) ,
}
print("\nRunning test_detect_rows_complex_3_white...")
for length, exp_val in expected.items():
result = gomoku.detect_rows(board, player, length)
assert result == exp_val, f"Length {length}: Expected {exp_val}, got {result}"
print("PASSED")
def test_search_max_complex_1():
"""Test Case 7: Search Max Complex Scenario 1"""
board = [['w', ' ', 'b', 'w', ' ', 'w', ' ', 'b'],
['w', ' ', 'w', 'w', 'b', 'w', 'w', 'b'],
['b', 'b', ' ', 'b', ' ', ' ', 'b', 'w'],
[' ', 'b', 'w', ' ', 'w', 'b', 'b', 'b'],
['b', 'b', 'w', 'b', 'w', 'b', ' ', 'w'],
['w', 'w', 'w', 'w', ' ', 'w', ' ', ' '],
[' ', 'b', 'w', 'b', 'w', ' ', 'w', 'w'],
[' ', ' ', 'w', 'b', ' ', 'b', 'w', 'w']]
print("\nRunning test_search_max_complex_1...")
gomoku.print_board(board)
result = gomoku.search_max(board)
expected = (2, 2)
assert result == expected, f"Expected {expected}, got {result}"
print("PASSED")
def test_search_max_complex_2():
"""Test Case 8: Search Max Complex Scenario 2"""
board = [['w', 'w', 'b', 'b', ' ', 'b', ' ', 'w'],
[' ', ' ', 'b', 'w', 'b', ' ', ' ', ' '],
[' ', 'b', ' ', ' ', 'w', 'b', 'w', 'b'],
['w', 'w', 'w', 'w', ' ', 'w', 'b', 'b'],
['b', 'b', 'b', 'b', ' ', 'b', ' ', 'w'],
['b', 'b', 'w', 'b', ' ', ' ', ' ', ' '],
['w', ' ', 'b', 'b', 'b', ' ', 'w', ' '],
['b', ' ', ' ', 'b', 'b', 'w', 'b', ' ']]
print("\nRunning test_search_max_complex_2...")
gomoku.print_board(board)
result = gomoku.search_max(board)
expected = (5, 4)
assert result == expected, f"Expected {expected}, got {result}"
print("PASSED")
if __name__ == '__main__':
test_detect_rows_complex_1_black()
test_detect_rows_complex_1_white()
test_detect_rows_complex_2_black()
test_detect_rows_complex_2_white()
test_detect_rows_complex_3_black()
test_detect_rows_complex_3_white()
test_search_max_complex_1()
test_search_max_complex_2()
print("\nAll hidden tests passed for test_hidden_student.py!")
</code></pre>
</div>
</details>
<!-- TEST 4: is_bounded -->
<details>
<summary>test_is_bounded_student.py</summary>
<div class="test-description">
Tests for <code>is_bounded</code>. Checks OPEN, SEMIOPEN, and CLOSED states in various directions.
</div>
<div class="code-wrapper">
<button class="copy-btn" onclick="copyCode(this)">Copy</button>
<pre><code>"""
TestIsBounded Student Test Suite
Test Cases:
1. test_len2_unbound_x
2. test_len2_unbound_x_white
3. test_len2_unbound_y
4. test_len3_unbound_y_constrained
5. test_len4_unbound_d_constrained
6. test_len2_bound_y
7. test_len2_bound_x
8. test_len3_bound_x_boarder
9. test_len4_bound_d_boarder
10. test_len4_bound_d_boarder_lower_right_white
11. test_len2_semi_y
12. test_len2_semi_x
13. test_len3_semi_x_boarder
14. test_len4_semi_d_boarder
15. test_len4_semi_d_boarder_lower_right_white
"""
import gomoku
def test_len2_unbound_x():
"""Test Case 1: Length 2 open sequence in x direction"""
board = [[' ',' ',' ',' ',' ',' ',' ',' '],
[' ','b','b',' ','w',' ',' ',' '],
[' ',' ',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.is_bounded(board,1, 2, 2, 0, 1).upper()
expected = "OPEN"
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len2_unbound_x PASSED")
def test_len2_unbound_x_white():
"""Test Case 2: Length 2 open sequence in x direction (white)"""
board = [[' ',' ',' ',' ',' ',' ',' ',' '],
[' ','b','b',' ','w',' ',' ',' '],
[' ',' ',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.is_bounded(board,2, 4, 2, 1, 0).upper()
expected = "OPEN"
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len2_unbound_x_white PASSED")
def test_len2_unbound_y():
"""Test Case 3: Length 2 open sequence in y direction"""
board = [[' ',' ',' ',' ',' ',' ',' ',' '],
[' ','b','b',' ','w',' ',' ',' '],
[' ','b',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.is_bounded(board,2, 1, 2, 1, 0).upper()
expected = "OPEN"
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len2_unbound_y PASSED")
def test_len3_unbound_y_constrained():
"""Test Case 4: Length 3 open sequence in y direction (constrained by other pieces)"""
board = [[' ',' ',' ',' ',' ',' ',' ',' '],
['b',' ','b',' ','w','w',' ',' '],
[' ','b','b',' ','w','w',' ',' '],
['b','b','b','w','w',' ',' ',' '],
[' ',' ',' ','w',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.is_bounded(board,3, 2, 3, 1, 0).upper()
expected = "OPEN"
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len3_unbound_y_constrained PASSED")
def test_len4_unbound_d_constrained():
"""Test Case 5: Length 4 open sequence in diagonal direction"""
board = [[' ','w',' ',' ',' ',' ',' ',' '],
['w','b','b',' ','w',' ',' ',' '],
[' ','b','b',' ','w',' ',' ',' '],
[' ',' ',' ','b','w',' ',' ',' '],
['b',' ',' ',' ','b','w',' ',' '],
[' ',' ',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.is_bounded(board,4, 4, 4, 1, 1).upper()
expected = "OPEN"
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len4_unbound_d_constrained PASSED")
def test_len2_bound_y():
"""Test Case 6: Length 2 closed sequence in y direction"""
board = [[' ','w',' ',' ',' ',' ',' ',' '],
[' ','b','b',' ',' ',' ',' ',' '],
['b','b',' ',' ',' ',' ',' ',' '],
[' ','w',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.is_bounded(board,2, 1, 2, 1, 0).upper()
expected = "CLOSED"
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len2_bound_y PASSED")
def test_len2_bound_x():
"""Test Case 7: Length 2 closed sequence in x direction"""
board = [[' ',' ','b',' ',' ',' ',' ',' '],
['w','b','b','w',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.is_bounded(board,1, 2, 2, 0, 1).upper()
expected = "CLOSED"
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len2_bound_x PASSED")
def test_len3_bound_x_boarder():
"""Test Case 8: Length 3 closed sequence in x direction (border)"""
board = [[' ',' ',' ',' ',' ',' ',' ',' '],
['b','b','b','w',' ',' ',' ',' '],
['w','b',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.is_bounded(board,1, 2, 3, 0, 1).upper()
expected = "CLOSED"
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len3_bound_x_boarder PASSED")
def test_len4_bound_d_boarder():
"""Test Case 9: Length 4 closed sequence in diagonal direction (border)"""
board = [['b',' ',' ',' ',' ',' ',' ',' '],
['w','b','b',' ','w',' ',' ',' '],
[' ',' ','b',' ',' ',' ',' ',' '],
['b','b','b','b',' ',' ',' ',' '],
[' ',' ',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ',' ','w',' ',' '],
[' ',' ',' ',' ',' ',' ','w',' '],
['w','w','w',' ',' ',' ',' ',' ']]
result = gomoku.is_bounded(board,3, 3, 4, 1, 1).upper()
expected = "CLOSED"
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len4_bound_d_boarder PASSED")
def test_len4_bound_d_boarder_lower_right_white():
"""Test Case 10: Length 4 closed sequence in diagonal direction (lower right, white)"""
board = [['b',' ','b','b',' ','b',' ',' '],
[' ',' ',' ','b','b',' ',' ',' '],
[' ','b',' ','w',' ',' ',' ',' '],
[' ',' ',' ','b','b',' ',' ',' '],
[' ','b',' ','b','w','w','w','w'],
[' ',' ',' ','b','w','w',' ',' '],
[' ',' ',' ','b','w',' ','w',' '],
['w','w','b','w','w',' ',' ','w']]
result = gomoku.is_bounded(board,7, 7, 4, 1, 1).upper()
expected = "CLOSED"
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len4_bound_d_boarder_lower_right_white PASSED")
def test_len2_semi_y():
"""Test Case 11: Length 2 semi-open sequence in y direction"""
board = [[' ','w',' ',' ',' ',' ',' ',' '],
[' ','b','b',' ',' ',' ',' ',' '],
['b','b','w',' ',' ',' ',' ',' '],
[' ',' ',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.is_bounded(board,2, 1, 2, 1, 0).upper()
expected = "SEMIOPEN"
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len2_semi_y PASSED")
def test_len2_semi_x():
"""Test Case 12: Length 2 semi-open sequence in x direction"""
board = [[' ',' ','b',' ',' ',' ',' ',' '],
['w','b','b',' ',' ',' ',' ',' '],
[' ',' ','w',' ',' ',' ',' ',' '],
[' ',' ',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.is_bounded(board,1, 2, 2, 0, 1).upper()
expected = "SEMIOPEN"
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len2_semi_x PASSED")
def test_len3_semi_x_boarder():
"""Test Case 13: Length 3 semi-open sequence in x direction (border)"""
board = [['b',' ','b',' ',' ',' ',' ',' '],
['w','b','b','w','w',' ',' ',' '],
['b','b','b',' ',' ',' ',' ',' '],
[' ',' ','w','w','w',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.is_bounded(board,2, 2, 3, 0, 1).upper()
expected = "SEMIOPEN"
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len3_semi_x_boarder PASSED")
def test_len4_semi_d_boarder():
"""Test Case 14: Length 4 semi-open sequence in diagonal direction (border)"""
board = [['b',' ',' ','b',' ',' ',' ',' '],
['w','b','b','b','w',' ',' ',' '],
[' ',' ','b','b',' ',' ',' ',' '],
['b','b','b','b','w',' ',' ',' '],
[' ',' ',' ','w',' ',' ',' ',' '],
[' ',' ',' ','w',' ','w',' ',' '],
[' ',' ',' ','w',' ',' ','w',' '],
['w','w','w','w',' ',' ',' ',' ']]
result = gomoku.is_bounded(board,3, 3, 4, 1, 1).upper()
expected = "SEMIOPEN"
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len4_semi_d_boarder PASSED")
def test_len4_semi_d_boarder_lower_right_white():
"""Test Case 15: Length 4 semi-open sequence in diagonal direction (lower right, white)"""
board = [['b',' ','b','b',' ',' ',' ',' '],
[' ',' ',' ','b','b',' ',' ',' '],
[' ',' ',' ','b',' ',' ',' ',' '],
[' ',' ',' ',' ','b',' ',' ',' '],
[' ',' ',' ','b','w','w','w','w'],
[' ',' ',' ','b','w','w',' ',' '],
[' ',' ',' ','b','w',' ','w',' '],
['w','w','b','b','w',' ',' ','w']]
result = gomoku.is_bounded(board,7, 7, 4, 1, 1).upper()
expected = "SEMIOPEN"
assert result == expected, f"Expected {expected}, but got {result}"
print("test_len4_semi_d_boarder_lower_right_white PASSED")
if __name__ == '__main__':
test_len2_unbound_x()
test_len2_unbound_x_white()
test_len2_unbound_y()
test_len3_unbound_y_constrained()
test_len4_unbound_d_constrained()
test_len2_bound_y()
test_len2_bound_x()
test_len3_bound_x_boarder()
test_len4_bound_d_boarder()
test_len4_bound_d_boarder_lower_right_white()
test_len2_semi_y()
test_len2_semi_x()
test_len3_semi_x_boarder()
test_len4_semi_d_boarder()
test_len4_semi_d_boarder_lower_right_white()
print("All tests passed for test_is_bounded_student.py!")
</code></pre>
</div>
</details>
<!-- TEST 5: is_empty -->
<details>
<summary>test_is_empty_student.py</summary>
<div class="test-description">
Basic validation for the <code>is_empty</code> function.
</div>
<div class="code-wrapper">
<button class="copy-btn" onclick="copyCode(this)">Copy</button>
<pre><code>"""
TestIsEmpty Student Test Suite
Test Cases:
1. test_with_empty_board
2. test_with_non_empty_board
"""
import gomoku
def test_with_empty_board():
"""Test Case 1: Check if an empty board returns True"""
empty_board = [[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.is_empty(empty_board)
expected = True
assert result == expected, f"Expected {expected}, but got {result}"
print("test_with_empty_board PASSED")
def test_with_non_empty_board():
"""Test Case 2: Check if a non-empty board returns False"""
not_empty_board = [[' ',' ',' ',' ','b','w',' ',' '],
[' ',' ',' ',' ','b','w',' ',' '],
[' ',' ',' ',' ','b','w',' ',' '],
[' ',' ',' ',' ','b','w',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.is_empty(not_empty_board)
expected = False
assert result == expected, f"Expected {expected}, but got {result}"
print("test_with_non_empty_board PASSED")
if __name__ == '__main__':
test_with_empty_board()
test_with_non_empty_board()
print("All tests passed for test_is_empty_student.py!")
</code></pre>
</div>
</details>
<!-- TEST 6: is_win -->
<details>
<summary>test_is_win_student.py</summary>
<div class="test-description">
Tests for win conditions ("White won", "Black won", "Draw", "Continue playing").
</div>
<div class="code-wrapper">
<button class="copy-btn" onclick="copyCode(this)">Copy</button>
<pre><code>"""
TestIsWin Student Test Suite
Test Cases:
1. test_simple_unbound_b_win
2. test_simple_unbound_w_win
3. test_simple_continue
4. test_draw
5. test_semi_bound_b_win1
6. test_semi_bound_b_win2
7. test_semi_w_win1
8. test_semi_w_win2
9. test_closed_win_b
10. test_closed_win_w
11. test_closed_win_complicated_board_b
"""
import gomoku
def test_simple_unbound_b_win():
"""Test Case 1: Simple unbound Black win (horizontal)"""
board = [[' ',' ',' ',' ',' ',' ',' ',' '],
[' ','b','b','b','b','b',' ',' '],
[' ',' ',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.is_win(board).upper()
expected = "BLACK WON"
assert result == expected, f"Expected {expected}, but got {result}"
print("test_simple_unbound_b_win PASSED")
def test_simple_unbound_w_win():
"""Test Case 2: Simple unbound White win (vertical)"""
board = [[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ','w',' '],
[' ',' ',' ',' ',' ',' ','w',' '],
[' ',' ',' ','b',' ',' ','w',' '],
[' ',' ',' ',' ',' ',' ','w',' '],
['b','b','b','b',' ',' ','w',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.is_win(board).upper()
expected = "WHITE WON"
assert result == expected, f"Expected {expected}, but got {result}"
print("test_simple_unbound_w_win PASSED")
def test_simple_continue():
"""Test Case 3: No winner, continue playing"""
board = [[' ',' ',' ',' ',' ',' ',' ',' '],
[' ','b','b',' ','w','w','w',' '],
[' ',' ',' ',' ','w','w','w',' '],
[' ','b','b',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ','b','b',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.is_win(board).upper()
expected = "CONTINUE PLAYING"
assert result == expected, f"Expected {expected}, but got {result}"
print("test_simple_continue PASSED")
def test_draw():
"""Test Case 4: Full board with no winner (Draw)"""
board = [['b','w','b','w','w','b','w','b'],
['b','w','b','w','w','b','w','b'],
['b','w','b','w','w','b','w','b'],
['b','w','b','w','w','b','w','b'],
['w','b','w','b','b','w','b','w'],
['w','b','w','b','b','w','b','w'],
['w','b','w','b','b','w','b','w'],
['w','b','w','b','b','w','b','w']]
result = gomoku.is_win(board).upper()
expected = "DRAW"
assert result == expected, f"Expected {expected}, but got {result}"
print("test_draw PASSED")
def test_semi_bound_b_win1():
"""Test Case 5: Semi-bounded Black win (vertical, top edge blocked)"""
board = [[' ','b',' ',' ',' ',' ',' ',' '],
[' ','b',' ',' ','w',' ',' ',' '],
[' ','b',' ',' ','w',' ',' ',' '],
[' ','b',' ',' ','w',' ',' ',' '],
[' ','b',' ',' ','w',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.is_win(board).upper()
expected = "BLACK WON"
assert result == expected, f"Expected {expected}, but got {result}"
print("test_semi_bound_b_win1 PASSED")
def test_semi_bound_b_win2():
"""Test Case 6: Semi-bounded Black win (vertical, blocked by white)"""
board = [[' ',' ',' ','w',' ',' ',' ',' '],
[' ',' ',' ','b','w',' ',' ',' '],
[' ',' ',' ','b','w',' ',' ',' '],
[' ',' ',' ','b','w',' ',' ',' '],
[' ',' ',' ','b',' ',' ',' ',' '],
[' ',' ',' ','b',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.is_win(board).upper()
expected = "BLACK WON"
assert result == expected, f"Expected {expected}, but got {result}"
print("test_semi_bound_b_win2 PASSED")
def test_semi_w_win1():
"""Test Case 7: Semi-bounded White win (vertical)"""
board = [[' ','w',' ',' ',' ',' ',' ',' '],
[' ','w',' ',' ','b',' ',' ',' '],
[' ','w',' ',' ','b',' ',' ',' '],
[' ','w',' ',' ','b',' ',' ',' '],
[' ','w',' ',' ','b',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.is_win(board).upper()
expected = "WHITE WON"
assert result == expected, f"Expected {expected}, but got {result}"
print("test_semi_w_win1 PASSED")
def test_semi_w_win2():
"""Test Case 8: Semi-bounded White win (vertical, blocked by black)"""
board = [[' ','b',' ',' ',' ',' ',' ',' '],
[' ','w',' ',' ','b',' ',' ',' '],
[' ','w',' ',' ','b',' ',' ',' '],
[' ','w',' ',' ','b',' ',' ',' '],
[' ','w',' ',' ','b',' ',' ',' '],
[' ','w',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.is_win(board).upper()
expected = "WHITE WON"
assert result == expected, f"Expected {expected}, but got {result}"
print("test_semi_w_win2 PASSED")
def test_closed_win_b():
"""Test Case 9: Closed Black win (horizontal)"""
board = [[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ','w',' ',' ',' ',' '],
['b','b','b','b','b','w',' ',' '],
[' ','w','w',' ','w',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.is_win(board).upper()
expected = "BLACK WON"
assert result == expected, f"Expected {expected}, but got {result}"
print("test_closed_win_b PASSED")
def test_closed_win_w():
"""Test Case 10: Closed White win (horizontal)"""
board = [['w','w','w','w','w','b',' ',' '],
[' ','b','b',' ',' ',' ',' ',' '],
['b','b',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.is_win(board).upper()
expected = "WHITE WON"
assert result == expected, f"Expected {expected}, but got {result}"
print("test_closed_win_w PASSED")
def test_closed_win_complicated_board_b():
"""Test Case 11: Closed Black win (vertical, complicated board)"""
board = [[' ','w',' ',' ',' ',' ',' ',' '],
[' ','b',' ',' ',' ',' ',' ',' '],
[' ','b','w','w','w','w',' ',' '],
[' ','b','b',' ',' ',' ',' ',' '],
[' ','b',' ','b',' ',' ',' ',' '],
[' ','b','w',' ',' ',' ',' ',' '],
[' ','w',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
result = gomoku.is_win(board).upper()
expected = "BLACK WON"
assert result == expected, f"Expected {expected}, but got {result}"
print("test_closed_win_complicated_board_b PASSED")
if __name__ == '__main__':
test_simple_unbound_b_win()
test_simple_unbound_w_win()
test_simple_continue()
test_draw()
test_semi_bound_b_win1()
test_semi_bound_b_win2()
test_semi_w_win1()
test_semi_w_win2()
test_closed_win_b()
test_closed_win_w()
test_closed_win_complicated_board_b()
print("All tests passed for test_is_win_student.py!")
</code></pre>
</div>
</details>
<!-- TEST 7: public -->
<details>
<summary>test_public_student.py</summary>
<div class="test-description">
Tests corresponding specifically to the figures (1-5) provided in the project PDF description.
</div>
<div class="code-wrapper">
<button class="copy-btn" onclick="copyCode(this)">Copy</button>
<pre><code>"""
TestPublic Student Test Suite
These tests correspond to the figures provided in the project description.
Test Cases:
1. test_public_figure_1: Open sequence with 3 white stones (1,0)
2. test_public_figure_2: Semi-open sequence with 3 black stones (0,1)
3. test_public_figure_3: Closed sequence with 4 white stones (0,1)
4. test_public_figure_4: Closed sequence with 3 black stones (1,1)
5. test_public_figure_5: Semi-open sequence with 4 white stones (1,-1)
"""
import gomoku
def b2s(board):
"""Helper to convert board to string for debugging"""
s = "*"
for i in range(len(board[0])-1):
s += str(i%10) + "|"
s += str((len(board[0])-1)%10)
s += "*\n"
for i in range(len(board)):
s += str(i%10)
for j in range(len(board[0])-1):
s += str(board[i][j]) + "|"
s += str(board[i][len(board[0])-1])
s += "*\n"
s += (len(board[0])*2 + 1)*"*"
return s
def test_public_figure_1():
"""
Figure 1: An open sequence with 3 white stones. The direction is (1,0).
The last stone is at location (6,1).
"""
print("\nRunning test_public_figure_1...")
# 0 1 2 3 4 5 6 7
board = [[' ',' ',' ',' ',' ',' ',' ',' '], # 0
[' ',' ',' ',' ',' ',' ',' ',' '], # 1
[' ',' ',' ',' ',' ',' ',' ',' '], # 2
[' ',' ',' ',' ',' ',' ',' ',' '], # 3
[' ','w',' ',' ',' ',' ',' ',' '], # 4
[' ','w',' ',' ',' ',' ',' ',' '], # 5
[' ','w',' ',' ',' ',' ',' ',' '], # 6
[' ',' ',' ',' ',' ',' ',' ',' ']] # 7
# 1. Check is_empty
assert gomoku.is_empty(board) == False, f"Board is not empty, but is_empty returned True. \n{b2s(board)}"
# 2. Check is_bounded
# Sequence ends at (6,1), length 3, direction (1,0) [vertical]
res_bounded = gomoku.is_bounded(board, 6, 1, 3, 1, 0)
assert res_bounded == "OPEN", f"The sequence should be OPEN, got {res_bounded} \n{b2s(board)}"
# 3. Check detect_row
# Check column 1 starting at (0,1) going down (1,0)
res_row = gomoku.detect_row(board, 'w', 0, 1, 3, 1, 0)
assert res_row == (1, 0), f"There should be one open sequence of length 3 for white in column 1, got {res_row} \n{b2s(board)}"
# 4. Check detect_rows
res_rows = gomoku.detect_rows(board, 'w', 3)
assert res_rows == (1, 0), f"There should be one open sequence of length 3 for white on the board, got {res_rows} \n{b2s(board)}"
print("PASSED")
def test_public_figure_2():
"""
Figure 2: A semi-open sequence with 3 black stones. The direction is (0,1).
The last stone is at location (3,5).
"""
print("\nRunning test_public_figure_2...")
# 0 1 2 3 4 5 6 7
board = [[' ',' ',' ',' ',' ',' ',' ',' '], # 0
[' ',' ',' ',' ',' ',' ',' ',' '], # 1
[' ',' ',' ',' ',' ',' ',' ',' '], # 2
[' ',' ',' ','b','b','b','w',' '], # 3
[' ',' ',' ',' ',' ',' ',' ',' '], # 4
[' ',' ',' ',' ',' ',' ',' ',' '], # 5
[' ',' ',' ',' ',' ',' ',' ',' '], # 6
[' ',' ',' ',' ',' ',' ',' ',' ']] # 7
# 1. Check is_empty
assert gomoku.is_empty(board) == False, f"Board is not empty, but is_empty returned True. \n{b2s(board)}"
# 2. Check is_bounded
# Sequence ends at (3,5), length 3, direction (0,1) [horizontal]
res_bounded = gomoku.is_bounded(board, 3, 5, 3, 0, 1)
assert res_bounded == "SEMIOPEN", f"The sequence should be SEMIOPEN, got {res_bounded} \n{b2s(board)}"
# 3. Check detect_row
# Check row 3 starting at (3,0) going right (0,1)
res_row = gomoku.detect_row(board, 'b', 3, 0, 3, 0, 1)
assert res_row == (0, 1), f"There should be one semi-open sequence of length 3 for black in row 3, got {res_row} \n{b2s(board)}"
# 4. Check detect_rows
res_rows = gomoku.detect_rows(board, 'b', 3)
assert res_rows == (0, 1), f"There should be one semi-open sequence of length 3 for black on the board, got {res_rows} \n{b2s(board)}"
print("PASSED")
def test_public_figure_3():
"""
Figure 3: A closed sequence with 4 white stones. The direction is (0,1).
The last stone is at location (3,3).
"""
print("\nRunning test_public_figure_3...")
# 0 1 2 3 4 5 6 7
board = [[' ',' ',' ',' ',' ',' ',' ',' '], # 0
[' ',' ',' ',' ',' ',' ',' ',' '], # 1
[' ',' ',' ',' ',' ',' ',' ',' '], # 2
['w','w','w','w','b',' ',' ',' '], # 3
[' ',' ',' ',' ',' ',' ',' ',' '], # 4
[' ',' ',' ',' ',' ',' ',' ',' '], # 5
[' ',' ',' ',' ',' ',' ',' ',' '], # 6
[' ',' ',' ',' ',' ',' ',' ',' ']] # 7
# 1. Check is_empty
assert gomoku.is_empty(board) == False, f"Board is not empty, but is_empty returned True. \n{b2s(board)}"
# 2. Check is_bounded
# Sequence ends at (3,3), length 4, direction (0,1) [horizontal]
# Blocked by left edge and black stone at (3,4)
res_bounded = gomoku.is_bounded(board, 3, 3, 4, 0, 1)
assert res_bounded == "CLOSED", f"The sequence should be CLOSED, got {res_bounded} \n{b2s(board)}"
# 3. Check detect_row
# Check row 3 starting at (3,0) going right (0,1)
# Closed sequences are NOT counted in detect_rows usually (returns open, semi_open)
res_row = gomoku.detect_row(board, 'w', 3, 0, 4, 0, 1)
assert res_row == (0, 0), f"There should be no open or semi-open sequences of length 4 for white in row 3, got {res_row} \n{b2s(board)}"
# 4. Check detect_rows
res_rows = gomoku.detect_rows(board, 'w', 4)
assert res_rows == (0, 0), f"There should be no open or semi-open sequences of length 4 for white on the board, got {res_rows} \n{b2s(board)}"
print("PASSED")
def test_public_figure_4():
"""
Figure 4: A closed sequence with 3 black stones. The direction is (1,1).
The last stone is at location (7,2).
"""
print("\nRunning test_public_figure_4...")
# 0 1 2 3 4 5 6 7
board = [[' ',' ',' ',' ',' ',' ',' ',' '], # 0
[' ',' ',' ',' ',' ',' ',' ',' '], # 1
[' ',' ',' ',' ',' ',' ',' ',' '], # 2
[' ',' ',' ',' ',' ',' ',' ',' '], # 3
[' ',' ',' ',' ',' ',' ',' ',' '], # 4
['b',' ',' ',' ',' ',' ',' ',' '], # 5
[' ','b',' ',' ',' ',' ',' ',' '], # 6
[' ',' ','b',' ',' ',' ',' ',' ']] # 7
# 1. Check is_empty
assert gomoku.is_empty(board) == False, f"Board is not empty, but is_empty returned True. \n{b2s(board)}"
# 2. Check is_bounded
# Sequence ends at (7,2), length 3, direction (1,1) [diagonal]
# Blocked by left edge (start) and bottom edge (end)
res_bounded = gomoku.is_bounded(board, 7, 2, 3, 1, 1)
assert res_bounded == "CLOSED", f"The sequence should be CLOSED, got {res_bounded} \n{b2s(board)}"
# 3. Check detect_row
# Check diagonal starting at (5,0) going (1,1)
res_row = gomoku.detect_row(board, 'b', 5, 0, 3, 1, 1)
assert res_row == (0, 0), f"There should be no open or semi-open sequences of length 3 for black in the diagonal, got {res_row} \n{b2s(board)}"
# 4. Check detect_rows
res_rows = gomoku.detect_rows(board, 'b', 3)
assert res_rows == (0, 0), f"There should be no open or semi-open sequences of length 3 for black on the board, got {res_rows} \n{b2s(board)}"
print("PASSED")
def test_public_figure_5():
"""
Figure 5: A semi-open sequence with 4 white stones. The direction is (1,-1).
The last stone is at location (3,3).
"""
print("\nRunning test_public_figure_5...")
# 0 1 2 3 4 5 6 7
board = [[' ',' ',' ',' ',' ',' ','w',' '], # 0
[' ',' ',' ',' ',' ','w',' ',' '], # 1
[' ',' ',' ',' ','w',' ',' ',' '], # 2
[' ',' ',' ','w',' ',' ',' ',' '], # 3
[' ',' ',' ',' ',' ',' ',' ',' '], # 4
[' ',' ',' ',' ',' ',' ',' ',' '], # 5
[' ',' ',' ',' ',' ',' ',' ',' '], # 6
[' ',' ',' ',' ',' ',' ',' ',' ']] # 7
# 1. Check is_empty
assert gomoku.is_empty(board) == False, f"Board is not empty, but is_empty returned True. \n{b2s(board)}"
# 2. Check is_bounded
# Sequence ends at (3,3), length 4, direction (1,-1) [reverse diagonal]
# Start is (0,6). One side (0,6) is blocked by top edge. End (3,3) is open.
res_bounded = gomoku.is_bounded(board, 3, 3, 4, 1, -1)
assert res_bounded == "SEMIOPEN", f"The sequence should be SEMIOPEN, got {res_bounded} \n{b2s(board)}"
# 3. Check detect_row
# Check diagonal starting at (0,6) going (1,-1)
res_row = gomoku.detect_row(board, 'w', 0, 6, 4, 1, -1)
assert res_row == (0, 1), f"There should be one semi-open sequence of length 4 for white in the diagonal, got {res_row} \n{b2s(board)}"
# 4. Check detect_rows
res_rows = gomoku.detect_rows(board, 'w', 4)
assert res_rows == (0, 1), f"There should be one semi-open sequence of length 4 for white on the board, got {res_rows} \n{b2s(board)}"
print("PASSED")
if __name__ == '__main__':
test_public_figure_1()
test_public_figure_2()
test_public_figure_3()
test_public_figure_4()
test_public_figure_5()
print("All tests passed for test_public_student.py!")
</code></pre>
</div>
</details>
<!-- TEST 8: search_max -->
<details>
<summary>test_search_max_student.py</summary>
<div class="test-description">
Tests for the AI logic <code>search_max</code>. Ensures the computer picks the optimal move.
</div>
<div class="code-wrapper">
<button class="copy-btn" onclick="copyCode(this)">Copy</button>
<pre><code>"""
TestSearchMax Student Test Suite
Test Cases:
1. test_search_max_simple
2. test_search_max_top_left_corner
3. test_search_max_no_over_write
"""
import gomoku
def test_search_max_simple():
"""Test Case 1: Search max on a board with vertical columns"""
board = [[' ',' ',' ',' ','b','w',' ',' '],
[' ',' ',' ',' ','b','w',' ',' '],
[' ',' ',' ',' ','b','w',' ',' '],
[' ',' ',' ',' ','b','w',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
print("Testing search_max simple...")
gomoku.print_board(board)
result = gomoku.search_max(board)
expected = (4, 4)
# Note: This test relies on your detect_rows implementation being correct.
assert result == expected, f"Expected {expected}, but got {result}"
print("test_search_max_simple PASSED")
def test_search_max_top_left_corner():
"""Test Case 2: Search max finding move at (0,0) to block or win"""
board = [[' ',' ',' ',' ',' ',' ',' ',' '],
['w','b',' ',' ',' ',' ',' ',' '],
['w',' ','b',' ',' ',' ',' ',' '],
['w',' ',' ','b',' ',' ',' ',' '],
['w',' ',' ',' ','b',' ',' ',' '],
['b',' ',' ',' ',' ','w',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']]
print("Testing search_max top left corner...")
gomoku.print_board(board)
result = gomoku.search_max(board)
expected = (0, 0)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_search_max_top_left_corner PASSED")
def test_search_max_no_over_write():
"""Test Case 3: Search max should valid empty spot and not overwrite stones"""
board = [['b',' ',' ',' ',' ',' ',' ',' '],
['w','w',' ',' ',' ',' ',' ',' '],
['w',' ','b','b',' ',' ',' ',' '],
['w',' ','b','b',' ',' ',' ',' '],
['w','b',' ',' ','b',' ',' ',' '],
['b','w',' ',' ',' ','b',' ',' '],
[' ',' ','w',' ',' ',' ','w',' '],
[' ',' ',' ','w',' ',' ',' ',' ']]
print("Testing search_max no overwrite...")
gomoku.print_board(board)
result = gomoku.search_max(board)
expected = (1, 4)
assert result == expected, f"Expected {expected}, but got {result}"
print("test_search_max_no_over_write PASSED")
if __name__ == '__main__':
# These tests assume your detect_rows and is_bounded functions work correctly.
test_search_max_simple()
test_search_max_top_left_corner()
test_search_max_no_over_write()
print("All tests passed for test_search_max_student.py!")
</code></pre>
</div>
</details>
<script>
function copyCode(button) {
const pre = button.nextElementSibling;
const code = pre.innerText;
navigator.clipboard.writeText(code).then(() => {
const originalText = button.innerText;
button.innerText = 'Copied!';
button.style.backgroundColor = 'rgba(40, 167, 69, 0.5)';
button.style.borderColor = 'rgba(40, 167, 69, 0.8)';
setTimeout(() => {
button.innerText = originalText;
button.style.backgroundColor = '';
button.style.borderColor = '';
}, 2000);
}).catch(err => {
console.error('Failed to copy text: ', err);
button.innerText = 'Error';
});
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment