From b70c86e6b87f11986b4adb80d3b64892838664f0 Mon Sep 17 00:00:00 2001 From: hzhang Date: Fri, 31 Jan 2025 13:12:35 +0000 Subject: [PATCH] improve: more data generators --- DataGenerator/CircleGenerator.py | 2 + DataGenerator/InvariantPatternGenerator.py | 26 ++++++++++ DataGenerator/LineGenerator.py | 59 ++++++++++++++++++++++ DataGenerator/RandomGenerator.py | 24 +++++++++ 4 files changed, 111 insertions(+) create mode 100644 DataGenerator/InvariantPatternGenerator.py create mode 100644 DataGenerator/LineGenerator.py create mode 100644 DataGenerator/RandomGenerator.py diff --git a/DataGenerator/CircleGenerator.py b/DataGenerator/CircleGenerator.py index 754442f..2e85295 100644 --- a/DataGenerator/CircleGenerator.py +++ b/DataGenerator/CircleGenerator.py @@ -42,6 +42,8 @@ class CircleGenerator(DataGenerator): while (cx, cy, radius) in generated: cx, cy, radius = self.random_config() for tx, ty in circle_generator(cx, cy, radius): + if tx > self.width or ty > self.height or tx < 0 or ty < 0: + continue b.lives.add((tx, ty)) if len(b.try_evaluate()) == 0: success = False diff --git a/DataGenerator/InvariantPatternGenerator.py b/DataGenerator/InvariantPatternGenerator.py new file mode 100644 index 0000000..e0f1006 --- /dev/null +++ b/DataGenerator/InvariantPatternGenerator.py @@ -0,0 +1,26 @@ +from Board import Board +from DataGenerator import DataGenerator + + +class Pattern: + def __init__(self, pattern: set[tuple[int, int]], min_size: [int, int]): + self.pattern = pattern + self.min_size = min_size + +base_patterns = [ + Pattern({(0,0), (0, 1), {1, 0}, (1, 1)}, (2, 2)), + Pattern({(2,1), (1, 2), {2, 3}, (3, 2)}, (3, 3)), + Pattern({(1,2), (1, 3), {2, 1}, (2, 3), (3, 1), (3, 2)}, (3, 3)), + Pattern({(1, 1), (1, 2), (2, 1), (2, 3), (3, 2)}, (3, 3)), + Pattern({(2,1), (1, 2), (1, 3), (2, 4), (3, 3), {3, 2}}, (3, 4)), + Pattern({(1, 2), (1,3), {2, 1}, (2, 4), (3, 1), (3, 3), (4, 2)}, (4, 4)), + Pattern({(1, 2), (1, 3), (2, 1), (2, 4), (3, 1), (3, 4), (4, 2), (4, 3)}, (4, 4)), + Pattern({(1, 2), (1, 3), (2, 1), (2, 4), (3, 2), (3, 5), (4, 3), (4, 4)}, (4, 5)), + Pattern({(1, 1), (1, 3), (1, 4), (2, 1), (2, 2), (2, 4)}, (2, 4)), + +] + +class InvariantPatternGenerator(DataGenerator): + + def generate(self, amount: int) -> list[Board]: + pass \ No newline at end of file diff --git a/DataGenerator/LineGenerator.py b/DataGenerator/LineGenerator.py new file mode 100644 index 0000000..db880c6 --- /dev/null +++ b/DataGenerator/LineGenerator.py @@ -0,0 +1,59 @@ +import random +from Board import Board +from DataGenerator import DataGenerator + + +def bresenham_line(x1, y1, x2, y2): + dx = abs(x2 - x1) + sx = 1 if x1 < x2 else -1 + dy = -abs(y2 - y1) + sy = 1 if y1 < y2 else -1 + err = dx + dy + + while True: + yield x1, y1 + if x1 == x2 and y1 == y2: + break + e2 = 2 * err + if e2 >= dy: + err += dy + x1 += sx + if e2 <= dx: + err += dx + y1 += sy + + +class LineGenerator(DataGenerator): + def generate(self, amount: int) -> list[Board]: + res = [] + generated = set() + for _ in range(amount): + success = False + while not success: + success = True + b = Board(self.width, self.height, self.qx, self.qy) + x1, y1, x2, y2 = self.random_config() + + while (x1, y1, x2, y2) in generated: + x1, y1, x2, y2 = self.random_config() + + for tx, ty in bresenham_line(x1, y1, x2, y2): + if 0 <= tx < self.width and 0 <= ty < self.height: + b.lives.add((tx, ty)) + if len(b.try_evaluate()) == 0: + success = False + continue + generated.add((x1, y1, x2, y2)) + res.append(b) + + return res + + def random_config(self): + while True: + x1 = random.randint(0, self.width - 1) + y1 = random.randint(0, self.height - 1) + x2 = random.randint(0, self.width - 1) + y2 = random.randint(0, self.height - 1) + if x1 != x2 or y1 != y2: + break + return x1, y1, x2, y2 diff --git a/DataGenerator/RandomGenerator.py b/DataGenerator/RandomGenerator.py new file mode 100644 index 0000000..0110076 --- /dev/null +++ b/DataGenerator/RandomGenerator.py @@ -0,0 +1,24 @@ +import random + +from Board import Board +from DataGenerator import DataGenerator + + +class RandomGenerator(DataGenerator): + def generate(self, amount: int) -> list[Board]: + res = [] + for _ in range(amount): + success = False + while not success: + success = True + b = Board(self.width, self.height, self.qx, self.qy) + amount = random.randint(10, self.width * self.height) + for _ in range(amount): + x, y = random.randint(0, self.width - 1), random.randint(0, self.height - 1) + b.toggle(x, y) + if len(b.try_evaluate()) == 0: + success = False + continue + res.append(b) + + return res