You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
3.9 KiB
Python

from math import sqrt
from alphabet import *
import random
HORIZONTAL = 0
VERTICAL = 1
class WordGrid:
def __init__(self, width) -> None:
self.grid = []
self.width = width
self.area = width**2
self.cheated = False
# creating the grid array
for col in range(self.area):
self.grid.append(get_random_letter())
self.available_spots = []
# all the available spots that a letter can be placed
# True: can be placed
# False: can not be placed
for spot in range(self.area):
self.available_spots.append(True) # all spots are available at the beginning
# generates the word grid with words
# if this method is not called before printing the grid,
# it will print just some random letters
def generate_with_words(self, words):
# check if there are too much letters
if self.can_generate(words):
for word in words:
finded_place_to_enter_word = False
while not finded_place_to_enter_word:
# chooses a random direction
random_direction = random.choice([HORIZONTAL, VERTICAL])
# random x and y positions of the first letter of the current word
random_x = random.randint(0, self.width-1)
random_y = random.randint(0, self.width-1)
# making sure the word won't go out of bounds
if random_x + len(word) > self.width and random_direction == HORIZONTAL:
random_x -= (random_x + len(word)) - self.width
if random_y + len(word) > self.width and random_direction == VERTICAL:
random_y -= (random_y + len(word)) - self.width
# checking if the word can be placed before placing it
if self.is_placeable(word, random_x, random_y, random_direction):
self.place_word(word, random_x, random_y, random_direction)
finded_place_to_enter_word = True
# when generating finishes, print itself
self.print()
# sets a word in a position and with a particular direction
def place_word(self, word, x, y, direction):
# for every letter on the word
for l in range(len(word)):
if direction == HORIZONTAL:
# place horizontally
self.grid[x+l + y * self.width] = "\033[32m" + word[l] + "\033[0m" if self.cheated else word[l]
self.available_spots[x+l + y * self.width] = False # making the horizontal spot unavaliable
elif direction == VERTICAL:
# place vertically
self.grid[x + (y+l) * self.width] = "\033[32m" + word[l] + "\033[0m" if self.cheated else word[l]
self.available_spots[x + (y+l) * self.width] = False # making the vertical spot unavaliable
# checks if a word can be placed in a position and with a particular direction
def is_placeable(self, word, x, y, direction):
# for every letter on the word
for l in range(len(word)):
spot_available = self.available_spots[x+l + y * self.width] if direction == HORIZONTAL else self.available_spots[x + (y+l) * self.width]
# if the spot is available, then continue checking
if spot_available:
continue
# if a spot is unavaliable, then is not placeable, returns false
else:
return False
# if the loop finishes without returning false, it means that is placeable, returns true
return True
def can_generate(self, words):
letter_count = 0
for word in words:
for letter in word:
letter_count += 1
# if there are much more letters than the grid area
if letter_count > self.area:
print("\nToo many words for a little grid!")
return False
if len(word) > self.width:
print(f"\nYou entered a word too big for the grid size! (Grid size: {self.width})")
return False
return True
# prints the grid on the terminal
def print(self):
print("\033[96m┌" + (""*(2*(self.width)+1)) + "\033[0m" ) # just a nice little line
for y in range(self.width):
print("\033[96m│\033[0m", end=" ")
for x in range(self.width):
print(self.grid[x + y * self.width], end=" ")
print("\033[96m│\033[0m")
print("\033[96m└" + (""*(2*(self.width)+1)) + "\033[0m" )