WIP
This commit is contained in:
@ -1,6 +1,6 @@
|
|||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import List, Tuple, Optional
|
from typing import List, Tuple, Optional
|
||||||
from .dictionary import Dictionary, Word
|
from multiplayer_crosswords.dictionary import Dictionary, Word
|
||||||
|
|
||||||
class Orientation(Enum):
|
class Orientation(Enum):
|
||||||
HORIZONTAL = 1
|
HORIZONTAL = 1
|
||||||
@ -86,3 +86,15 @@ class Crossword:
|
|||||||
''.join(cell if cell else '.' for cell in row)
|
''.join(cell if cell else '.' for cell in row)
|
||||||
for row in self.grid
|
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)
|
||||||
55
multiplayer_crosswords/crossword_generators.py
Normal file
55
multiplayer_crosswords/crossword_generators.py
Normal 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)
|
||||||
@ -128,7 +128,7 @@ def main():
|
|||||||
words.append(word)
|
words.append(word)
|
||||||
return words
|
return words
|
||||||
|
|
||||||
N = 500_000
|
N = 100_000
|
||||||
MIN_WORD_LENGTH = 4
|
MIN_WORD_LENGTH = 4
|
||||||
MAX_WORD_LENGTH = 8
|
MAX_WORD_LENGTH = 8
|
||||||
dummy_words = generate_dummy_words(N, MIN_WORD_LENGTH, MAX_WORD_LENGTH)
|
dummy_words = generate_dummy_words(N, MIN_WORD_LENGTH, MAX_WORD_LENGTH)
|
||||||
|
|||||||
@ -85,3 +85,15 @@ def test_placed_words_tracking():
|
|||||||
assert placed.row == 1
|
assert placed.row == 1
|
||||||
assert placed.col == 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
|
||||||
49
tests/test_crossword_generators.py
Normal file
49
tests/test_crossword_generators.py
Normal 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
|
||||||
Reference in New Issue
Block a user