This commit is contained in:
2025-06-08 20:04:42 +02:00
parent 175371ee00
commit e555df0ca2
5 changed files with 132 additions and 4 deletions

View File

@ -1,6 +1,6 @@
from enum import Enum
from typing import List, Tuple, Optional
from .dictionary import Dictionary, Word
from multiplayer_crosswords.dictionary import Dictionary, Word
class Orientation(Enum):
HORIZONTAL = 1
@ -85,4 +85,16 @@ class Crossword:
return '\n'.join(
''.join(cell if cell else '.' for cell in row)
for row in self.grid
)
)
if __name__ == "__main__":
# Example usage
dictionary = Dictionary()
dictionary.add_word(Word("hello", ["greeting"], "easy"))
dictionary.add_word(Word("world", ["earth"], "easy"))
crossword = Crossword(5, 5, dictionary)
crossword.add_word(dictionary.words[0], 1, 0, Orientation.HORIZONTAL)
crossword.add_word(dictionary.words[1], 0, 4, Orientation.VERTICAL)
print(crossword)

View File

@ -0,0 +1,55 @@
# algorithms will be implemnented here
from typing import List, Tuple, Dict, Set, Optional
from multiplayer_crosswords.crossword import Crossword, Orientation
from multiplayer_crosswords.dictionary import Dictionary, Word
class Slot:
def __init__(self, row: int, col: int, orientation: Orientation, length: int):
self.row = row
self.col = col
self.orientation = orientation
self.length = length
self.id = (row, col, orientation) # Unique identifier
def __repr__(self):
return f"Slot(row={self.row}, col={self.col}, orientation={self.orientation}, length={self.length})"
def extract_slots(grid: List[List[str]], min_length: int = 2) -> List[Slot]:
rows, cols = len(grid), len(grid[0])
slots = []
# Horizontal slots
for r in range(rows):
c = 0
while c < cols:
while c < cols and grid[r][c] == '#':
c += 1
start = c
while c < cols and grid[r][c] != '#':
c += 1
length = c - start
if length >= min_length:
slots.append(Slot(r, start, Orientation.HORIZONTAL, length))
# Vertical slots
for c in range(cols):
r = 0
while r < rows:
while r < rows and grid[r][c] == '#':
r += 1
start = r
while r < rows and grid[r][c] != '#':
r += 1
length = r - start
if length >= min_length:
slots.append(Slot(start, c, Orientation.VERTICAL, length))
return slots
def slot_pattern(grid: List[List[str]], slot: Slot) -> str:
dr, dc = (0, 1) if slot.orientation == Orientation.HORIZONTAL else (1, 0)
pattern = []
for i in range(slot.length):
r, c = slot.row + dr * i, slot.col + dc * i
cell = grid[r][c]
pattern.append(cell if cell and cell != '#' else '*')
return ''.join(pattern)

View File

@ -128,7 +128,7 @@ def main():
words.append(word)
return words
N = 500_000
N = 100_000
MIN_WORD_LENGTH = 4
MAX_WORD_LENGTH = 8
dummy_words = generate_dummy_words(N, MIN_WORD_LENGTH, MAX_WORD_LENGTH)

View File

@ -84,4 +84,16 @@ def test_placed_words_tracking():
assert placed.word == word
assert placed.row == 1
assert placed.col == 1
assert placed.orientation == Orientation.VERTICAL
assert placed.orientation == Orientation.VERTICAL
def test_valid_hello_world_crossword():
cw = make_crossword()
assert cw.add_word(DummyWord("HELLO"), 1, 0, Orientation.HORIZONTAL)
assert cw.add_word(DummyWord("WORLD"), 0, 4, Orientation.VERTICAL)
assert str(cw).count('H') == 1
assert str(cw).count('E') == 1
assert str(cw).count('L') == 3
assert str(cw).count('O') == 1
assert str(cw).count('W') == 1
assert str(cw).count('R') == 1
assert str(cw).count('D') == 1

View File

@ -0,0 +1,49 @@
import pytest
from multiplayer_crosswords.crossword_generators import extract_slots, slot_pattern, Slot
from multiplayer_crosswords.crossword import Orientation
def test_extract_slots_simple():
grid = [
['', '', '', '#', ''],
['', '#', '', '', ''],
['', '', '', '', ''],
['#', '', '#', '', ''],
['', '', '', '', ''],
]
slots = extract_slots(grid, min_length=2)
# Should find horizontal and vertical slots of length >= 2
assert any(s.orientation == Orientation.HORIZONTAL and s.length == 3 for s in slots)
assert any(s.orientation == Orientation.VERTICAL and s.length == 3 for s in slots)
# No slot should start at a '#' cell
for slot in slots:
r, c = slot.row, slot.col
assert grid[r][c] != '#'
assert len(slots) == 10 # Total slots found
def test_slot_pattern():
grid = [
['a', '', '', '#', ''],
['', '#', '', '', ''],
['', '', '', '', ''],
['#', '', '#', '', ''],
['', '', '', '', ''],
]
slot = Slot(0, 0, Orientation.HORIZONTAL, 3)
pattern = slot_pattern(grid, slot)
assert pattern == 'a**'
slot2 = Slot(2, 1, Orientation.VERTICAL, 3)
pattern2 = slot_pattern(grid, slot2)
assert pattern2 == '***' # All empty cells in this slot
def test_extract_slots_min_length():
grid = [
['#', '', '', '#'],
['', '', '', ''],
['#', '', '', '#'],
]
slots = extract_slots(grid, min_length=3)
# Only slots of length 3 or more
assert all(slot.length >= 3 for slot in slots)
assert len(slots) == 3