Created
December 1, 2022 23:04
-
-
Save Stovoy/d4166272470b0ee036cb6da3ea769a24 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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