Skip to content

Instantly share code, notes, and snippets.

@Stovoy
Created December 1, 2022 23:04
Show Gist options
  • Save Stovoy/d4166272470b0ee036cb6da3ea769a24 to your computer and use it in GitHub Desktop.
Save Stovoy/d4166272470b0ee036cb6da3ea769a24 to your computer and use it in GitHub Desktop.
import math
import time
import pygame
class Vector:
def __init__(self, p1, p2):
self.x1, self.y1 = p1
self.x2, self.y2 = p2
# Rotation around cx, cy
def rotate(self, angle, cx, cy):
angle = angle * math.pi / 180
cos = math.cos(angle)
sin = math.sin(angle)
x1 = self.x1 - cx
y1 = self.y1 - cy
x2 = self.x2 - cx
y2 = self.y2 - cy
self.x1 = (x1 * cos + y1 * sin) + cx
self.y1 = (-x1 * sin + y1 * cos) + cy
self.x2 = (x2 * cos + y2 * sin) + cx
self.y2 = (-x2 * sin + y2 * cos) + cy
return self
def clone(self):
return Vector((self.x1, self.y1), (self.x2, self.y2))
def intersection(self, vector):
dx = (self.x1 - self.x2, vector.x1 - vector.x2)
dy = (self.y1 - self.y2, vector.y1 - vector.y2)
def det(p1, p2):
return p1[0] * p2[1] - p1[1] * p2[0]
div = det(dx, dy)
if div == 0:
return None
d = (det((self.x1, self.x2), (self.y1, self.y2)), det((vector.x1, vector.x2), (vector.y1, vector.y2)))
return det(d, dx) / div, det(d, dy) / div
def __repr__(self):
return f'{(self.x1, self.y1), (self.x2, self.y2)}'
def square_text(x, y):
return f'{chr(ord("a") + x)}{8 - y}'
def square_text_to_coords(square):
x, y = square[0], square[1]
return ord(x) - ord("a"), 8 - int(y)
def is_center_intersection(x, y):
return abs(round(x) - x) < 0.05 and abs(round(y) - y) < 0.05
width = 300
height = 300
screen_color = (0, 0, 0)
rotated_line_color = (0, 45, 0)
grid_color = (0, 0, 128)
piece_color = (128, 0, 0)
intersection_color = (255, 255, 255)
valid_color = (0, 80, 0)
special_line_color = (255, 255, 255)
scale = 15
offset_x = 5
offset_y = 5
def clear(screen):
screen.fill(screen_color)
def draw_grid(screen, lines, rotated):
for line in lines:
pygame.draw.line(screen, grid_color,
((line.x1 + offset_x) * scale,
(line.y1 + offset_y) * scale),
((line.x2 + offset_x) * scale,
(line.y2 + offset_y) * scale))
for line in rotated:
pygame.draw.line(screen, rotated_line_color,
((line.x1 + offset_x) * scale,
(line.y1 + offset_y) * scale),
((line.x2 + offset_x) * scale,
(line.y2 + offset_y) * scale))
def main():
screen = pygame.display.set_mode((width, height))
# Make grid
lines = []
for i in range(9):
lines.append(Vector((i, 0), (i, 8)))
for i in range(9):
lines.append(Vector((0, i), (8, i)))
rotated = []
# Make 12 vertical lines, starting from -2 to 9
for i in range(13):
rotated.append(Vector((i - 2, -2), (i - 2, 10)))
# Make 12 horizontal lines, starting from -2 to 9
for i in range(13):
rotated.append(Vector((-2, i - 2), (10, i - 2)))
# 22.5 for Left Tipsy Bishop, -22.5 for Right Tipsy Bishop
rotated = [line.rotate(22.5, 4, 4) for line in rotated]
intersections = []
for line in rotated:
for other_line in rotated:
if other_line == line:
continue
intersection = line.intersection(other_line)
if intersection is not None:
x, y = intersection
if 0 <= x <= 8 or 0 <= y <= 8:
intersections.append((x, y, line, other_line))
output_table = "|**Start**|Valid Squares|\n:--|:--|\n"
for y in reversed(range(8)):
for x in range(8):
square = square_text(x, y)
clear(screen)
draw_grid(screen, lines, rotated)
pygame.draw.rect(screen, piece_color, (
((x + offset_x) * scale + 5, (y + offset_y) * scale + 5), (offset_x, offset_y)))
origin_intersection = None
for intersection in intersections:
i_x, i_y, line_1, line_2 = intersection
if is_center_intersection(i_x, i_y):
continue
if x <= i_x <= x + 1 and y <= i_y <= y + 1:
origin_intersection = intersection
break
valid_squares = []
if origin_intersection is None:
output_table += f'{square}|--|\n'
else:
_, _, line_1, line_2 = origin_intersection
for intersection in intersections:
i_x, i_y, new_line_1, new_line_2 = intersection
if new_line_1 == line_1 or new_line_1 == line_2 or new_line_2 == line_1 or new_line_2 == line_2:
f_x, f_y = math.floor(i_x), math.floor(i_y)
if f_x < 0 or f_x > 7 or f_y < 0 or f_y > 7:
continue
if is_center_intersection(i_x, i_y):
for point in [
(round(i_x-1), round(i_y-1)),
(round(i_x-1), round(i_y)),
(round(i_x), round(i_y-1)),
(round(i_x), round(i_y)),
]:
valid_squares.append(square_text(*point))
pygame.draw.circle(screen, intersection_color,
((i_x + offset_x) * scale, (i_y + offset_y) * scale), 2)
valid_squares.append(square_text(f_x, f_y))
valid_squares = sorted(set(valid_squares))
valid_squares.remove(square)
output_table += f'{square}|{",".join(valid_squares)}|\n'
for line in [line_1, line_2]:
pygame.draw.line(screen, special_line_color,
((line.x1 + offset_x) * scale,
(line.y1 + offset_y) * scale),
((line.x2 + offset_x) * scale,
(line.y2 + offset_y) * scale))
for valid_square in valid_squares:
vx, vy = square_text_to_coords(valid_square)
pygame.draw.rect(screen, valid_color,
((vx * scale + offset_x * scale, vy * scale + offset_y * scale), (15, 15)))
pygame.draw.rect(screen, piece_color,
(((x + offset_x) * scale, (y + offset_y) * scale), (15, 15)))
pygame.display.flip()
pygame.event.pump()
time.sleep(0.2)
print(output_table)
pygame.display.flip()
time.sleep(10)
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment