├── graph ├── board.pyc ├── token.pyc ├── constants.pyc ├── constants.py ├── token.py ├── game.py ├── token.py.rage ├── board.py └── old_game.py ├── constants.py ├── README.md ├── token.py ├── game.py ├── board.py └── old_game.py /graph/board.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/v/blockade/master/graph/board.pyc -------------------------------------------------------------------------------- /graph/token.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/v/blockade/master/graph/token.pyc -------------------------------------------------------------------------------- /graph/constants.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/v/blockade/master/graph/constants.pyc -------------------------------------------------------------------------------- /constants.py: -------------------------------------------------------------------------------- 1 | from PySFML import sf 2 | num_rows = 7 3 | num_cols = 7 4 | 5 | box_width = 50 6 | box_height = 50 7 | 8 | win_width = 1024 9 | win_height = 768 10 | 11 | token_radius = 20 12 | 13 | black = sf.Color(0, 0, 0) 14 | white = sf.Color(255, 255, 255) 15 | 16 | red = sf.Color(255, 25, 25) 17 | blue = sf.Color(25, 25, 255) 18 | -------------------------------------------------------------------------------- /graph/constants.py: -------------------------------------------------------------------------------- 1 | from PySFML import sf 2 | num_rows = 7 3 | num_cols = 7 4 | 5 | box_width = 50 6 | box_height = 50 7 | 8 | win_width = 1024 9 | win_height = 768 10 | 11 | token_radius = 20 12 | 13 | black = sf.Color(0, 0, 0) 14 | white = sf.Color(255, 255, 255) 15 | 16 | red = sf.Color(255, 25, 25) 17 | blue = sf.Color(25, 25, 255) 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Blockade 2 | ========== 3 | This is another game made for the Game Design class I took. 4 | 5 | This game is a turn based strategy game, that's essentially a board game. The game logic is not implemented in the game, but if you are playing with another player, you can still play by the rules. 6 | 7 | Installation 8 | ------------ 9 | 10 | 1. Clone this repo. 11 | 2. Run python game.py. This program is compiled with Python2.7 and PySFML, so you'll need to get those as dependencies. 12 | 13 | Rules 14 | -------- 15 | 1. This is a two player game. The player on the left is trying to move the blue circle into the blue spaces, and the player on the right is trying to move the red circle into the red spaces. 16 | 2. On each turn, a player must either move their circle by one space (up, down, left, right) or place a blockade on the grid. 17 | 3. Neither player may pass through a blockade, whether it was placed by them or their opponent. 18 | 4. You may not move blockades that have already been placed. 19 | 5. You may not build a wall with blockades. This means that both players must always have a path to their goal, that is not fully closed off by blockades. 20 | 6. When a player can make no more moves, he loses. 21 | 22 | Configuration 23 | ------------- 24 | 25 | You can edit constants.py to change around the dimensions of the board. The rendering code isn't the cleanest so you might need to tweak some of it to correctly show the game. 26 | -------------------------------------------------------------------------------- /token.py: -------------------------------------------------------------------------------- 1 | from constants import * 2 | import math 3 | 4 | class Token: 5 | def __init__(self, type, color): 6 | self.type = type 7 | self.color = color 8 | self.dragged = False 9 | self.i, self.j = -1, -1 10 | if self.type == 'circle': 11 | self.shape = sf.Shape.Circle(0, 0, token_radius, color) 12 | elif self.type =='rect': 13 | self.shape = sf.Shape.Rectangle(0, 0, box_width, box_height, color) 14 | 15 | def draw(self, window, x=None, y=None): 16 | if x and y: 17 | self.set_center(x+box_width/2, y+box_height/2) 18 | 19 | window.Draw(self.shape) 20 | 21 | def get_center(self): 22 | if self.type == 'circle': 23 | return self.shape.GetPosition() 24 | elif self.type == 'rect': 25 | position = list(self.shape.GetPosition()) 26 | position[0] += box_width/2 27 | position[1] += box_height/2 28 | 29 | return position 30 | 31 | def set_center(self, x, y): 32 | if self.type == 'circle': 33 | return self.shape.SetPosition(x, y) 34 | elif self.type == 'rect': 35 | x -= box_width/2 36 | y -= box_height/2 37 | 38 | return self.shape.SetPosition(x, y) 39 | 40 | 41 | def update(self, InputHandler, window): 42 | if self.dragged: 43 | mx, my = window.ConvertCoords(InputHandler.GetMouseX(), InputHandler.GetMouseY()) 44 | self.set_center(mx, my) 45 | 46 | def mouse_over(self, InputHandler, window): 47 | x, y = window.ConvertCoords(InputHandler.GetMouseX(), InputHandler.GetMouseY()) 48 | cx, cy = self.shape.GetPosition() 49 | if self.type == 'circle': 50 | return math.sqrt((cx - x)**2 + (cy - y)**2) < token_radius 51 | 52 | elif self.type == 'rect': 53 | cx, cy = self.shape.GetPosition() 54 | cx, cy = int(cx), int(cy) 55 | x, y = int(x), int(y) 56 | rect = sf.IntRect(cx, cy, cx + box_width, cy + box_height) 57 | 58 | return rect.Contains(x, y) 59 | -------------------------------------------------------------------------------- /graph/token.py: -------------------------------------------------------------------------------- 1 | from constants import * 2 | import math 3 | 4 | class Token: 5 | def __init__(self, type, color): 6 | self.type = type 7 | self.color = color 8 | self.dragged = False 9 | self.i, self.j = -1, -1 10 | if self.type == 'circle': 11 | self.shape = sf.Shape.Circle(0, 0, token_radius, color) 12 | elif self.type =='rect': 13 | self.shape = sf.Shape.Rectangle(0, 0, box_width, box_height, color) 14 | 15 | def draw(self, window, x=None, y=None): 16 | if x and y: 17 | self.set_center(x+box_width/2, y+box_height/2) 18 | 19 | window.Draw(self.shape) 20 | 21 | def get_center(self): 22 | if self.type == 'circle': 23 | return self.shape.GetPosition() 24 | elif self.type == 'rect': 25 | position = list(self.shape.GetPosition()) 26 | position[0] += box_width/2 27 | position[1] += box_height/2 28 | 29 | return position 30 | 31 | def set_center(self, x, y): 32 | if self.type == 'circle': 33 | return self.shape.SetPosition(x, y) 34 | elif self.type == 'rect': 35 | x -= box_width/2 36 | y -= box_height/2 37 | 38 | return self.shape.SetPosition(x, y) 39 | 40 | 41 | def update(self, InputHandler, window): 42 | if self.dragged: 43 | mx, my = window.ConvertCoords(InputHandler.GetMouseX(), InputHandler.GetMouseY()) 44 | self.set_center(mx, my) 45 | 46 | def mouse_over(self, InputHandler, window): 47 | x, y = window.ConvertCoords(InputHandler.GetMouseX(), InputHandler.GetMouseY()) 48 | cx, cy = self.shape.GetPosition() 49 | if self.type == 'circle': 50 | return math.sqrt((cx - x)**2 + (cy - y)**2) < token_radius 51 | 52 | elif self.type == 'rect': 53 | cx, cy = self.shape.GetPosition() 54 | cx, cy = int(cx), int(cy) 55 | x, y = int(x), int(y) 56 | rect = sf.IntRect(cx, cy, cx + box_width, cy + box_height) 57 | 58 | return rect.Contains(x, y) 59 | -------------------------------------------------------------------------------- /game.py: -------------------------------------------------------------------------------- 1 | from board import Board 2 | from token import Token 3 | from constants import * 4 | from PySFML import sf 5 | import math, os, sys 6 | 7 | window = sf.RenderWindow(sf.VideoMode(win_width, win_height), "Blackode") 8 | InputHandler = window.GetInput() 9 | 10 | 11 | bcircle = Token('circle', blue) 12 | bcircle.set_center(150, win_height/2) 13 | rcircle = Token('circle', red) 14 | rcircle.set_center(win_width - 150, win_height/2) 15 | 16 | b = Board(bcircle, rcircle) 17 | running = True 18 | 19 | tokens = [] 20 | 21 | lx = 250 22 | rx = win_width - lx 23 | 24 | for i in range(num_cols - 1): 25 | y = 100 + (i * box_height * 2) 26 | 27 | token = Token('rect', blue) 28 | token.shape.SetPosition(lx , y) 29 | 30 | tokens.append(token) 31 | 32 | token = Token('rect', red) 33 | token.shape.SetPosition(rx, y) 34 | 35 | tokens.append(token) 36 | 37 | tokens.append(bcircle) 38 | tokens.append(rcircle) 39 | 40 | 41 | valid_paths = None 42 | 43 | while running: 44 | event = sf.Event() 45 | while window.GetEvent(event): 46 | if event.Type == sf.Event.Closed: 47 | running = False 48 | if event.Type == sf.Event.MouseButtonPressed: 49 | for token in tokens: 50 | if token.mouse_over(InputHandler, window): 51 | token.dragged = True 52 | if token.i >= 0 and token.j >= 0: 53 | b.grid[token.i][token.j] = None 54 | 55 | if token.type == 'rect': 56 | b.invalid = b.find_critical_nodes(valid_paths) 57 | print b.invalid 58 | if event.Type == sf.Event.MouseButtonReleased: 59 | for token in tokens: 60 | if token.dragged: 61 | token.dragged = False 62 | b.snap(window, token) 63 | b.invalid = set() 64 | valid_paths = b.get_valid_paths() 65 | window.Clear() 66 | b.draw(window) 67 | for t in tokens: 68 | t.update(InputHandler, window) 69 | t.draw(window) 70 | window.Display() 71 | -------------------------------------------------------------------------------- /graph/game.py: -------------------------------------------------------------------------------- 1 | from board import Board 2 | from token import Token 3 | from constants import * 4 | from PySFML import sf 5 | import math, os, sys 6 | 7 | window = sf.RenderWindow(sf.VideoMode(win_width, win_height), "Blackode") 8 | InputHandler = window.GetInput() 9 | 10 | 11 | bcircle = Token('circle', blue) 12 | bcircle.set_center(150, win_height/2) 13 | rcircle = Token('circle', red) 14 | rcircle.set_center(win_width - 150, win_height/2) 15 | 16 | b = Board(bcircle, rcircle) 17 | running = True 18 | 19 | tokens = [] 20 | 21 | lx = 250 22 | rx = win_width - lx 23 | 24 | for i in range(num_cols - 1): 25 | y = 100 + (i * box_height * 2) 26 | 27 | token = Token('rect', blue) 28 | token.shape.SetPosition(lx , y) 29 | 30 | tokens.append(token) 31 | 32 | token = Token('rect', red) 33 | token.shape.SetPosition(rx, y) 34 | 35 | tokens.append(token) 36 | 37 | tokens.append(bcircle) 38 | tokens.append(rcircle) 39 | 40 | 41 | b.valid_paths = None 42 | 43 | while running: 44 | event = sf.Event() 45 | while window.GetEvent(event): 46 | if event.Type == sf.Event.Closed: 47 | running = False 48 | if event.Type == sf.Event.MouseButtonPressed: 49 | for token in tokens: 50 | if token.mouse_over(InputHandler, window): 51 | token.dragged = True 52 | if token.i >= 0 and token.j >= 0: 53 | b.grid[token.i][token.j] = None 54 | 55 | if token.type == 'rect': 56 | b.invalid = b.find_critical_nodes(b.valid_paths) 57 | print b.invalid 58 | if event.Type == sf.Event.MouseButtonReleased: 59 | for token in tokens: 60 | if token.dragged: 61 | token.dragged = False 62 | b.snap(window, token) 63 | b.invalid = set() 64 | b.valid_paths = b.get_valid_paths() 65 | window.Clear() 66 | b.draw(window) 67 | for t in tokens: 68 | t.update(InputHandler, window) 69 | t.draw(window) 70 | window.Display() 71 | -------------------------------------------------------------------------------- /graph/token.py.rage: -------------------------------------------------------------------------------- 1 | from constants import * 2 | import math 3 | 4 | class Token: 5 | def __init__(self, type, color): 6 | self.type = type 7 | self.color = color 8 | self.dragged = False 9 | self.i, self.j = -1, -1 10 | if self.type == 'circle': 11 | self.shape = sf.Shape.Circle(0, 0, token_radius, color) 12 | self.shape.SetCenter(box_width/2, box_height/2) 13 | elif self.type =='rect': 14 | self.shape = sf.Shape.Rectangle(0, 0, box_width, box_height, color) 15 | self.shape.SetCenter(box_width/2, box_height/2) 16 | 17 | def draw(self, window, x=None, y=None): 18 | if x and y: 19 | self.shape.SetPosition(x, y) 20 | 21 | window.Draw(self.shape) 22 | 23 | def center(self): 24 | position = self.shape.GetPosition() 25 | 26 | center = self.shape.GetCenter() 27 | x, y = position[0] + center[0], position[1] + center[1] 28 | return position 29 | 30 | def set_center(self, px, py): 31 | center = self.shape.GetCenter() 32 | #print "px, py = ", px, py, " center = ", center 33 | #print "x, y = ", x, y 34 | 35 | if self.type == 'circle' and False: 36 | x, y = px - center[0], py - center[1] 37 | else: 38 | x, y = px, py 39 | 40 | self.shape.SetPosition(x, y) 41 | 42 | 43 | def update(self, InputHandler, window): 44 | if self.dragged: 45 | print " call me darh" 46 | mx, my = window.ConvertCoords(InputHandler.GetMouseX(), InputHandler.GetMouseY()) 47 | self.set_center(mx, my) 48 | 49 | print "Shape Position = %s Center = %s " % (self.shape.GetPosition(), self.shape.GetCenter()) 50 | 51 | def mouse_over(self, InputHandler, window): 52 | x, y = window.ConvertCoords(InputHandler.GetMouseX(), InputHandler.GetMouseY()) 53 | cx, cy = self.center() 54 | if self.type == 'circle': 55 | return math.sqrt((cx - x)**2 + (cy - y)**2) < token_radius 56 | 57 | elif self.type == 'rect': 58 | cx, cy = self.shape.GetPosition() 59 | center = self.shape.GetCenter() 60 | cx -= center[0] 61 | cy -= center[1] 62 | cx, cy = int(cx), int(cy) 63 | x, y = int(x), int(y) 64 | rect = sf.IntRect(cx, cy, cx + box_width, cy + box_width) 65 | 66 | return rect.Contains(x, y) 67 | -------------------------------------------------------------------------------- /board.py: -------------------------------------------------------------------------------- 1 | from constants import * 2 | from PySFML import sf 3 | class Board: 4 | def __init__(self, blue, red): 5 | self.grid = [] 6 | self.blue = blue 7 | self.red = red 8 | self.invalid = set() 9 | for i in range(num_rows): 10 | self.grid.append([]) 11 | for j in range(num_cols): 12 | self.grid[i].append(None) 13 | 14 | def draw(self, window): 15 | startx = win_width/2 16 | starty = win_height/2 17 | startx, starty = window.ConvertCoords(startx, starty) 18 | startx -= num_cols * box_width/2 19 | starty -= num_rows * box_height/2 20 | 21 | startx, starty = (400, 200) 22 | for i, row in enumerate(self.grid): 23 | y = starty + (i * box_height) 24 | for j, square in enumerate(row): 25 | x = startx + (j * box_width) 26 | color = sf.Color(255, 255, 255) 27 | if j == 0: 28 | color = red 29 | elif j == num_cols - 1: 30 | color = blue 31 | 32 | bg_color = sf.Color(0, 0, 0) 33 | if (i, j) in self.invalid: 34 | bg_color = sf.Color(150, 25, 25) 35 | 36 | box = sf.Shape.Rectangle(x, y, x + box_width, y + box_height, bg_color, 1, color) 37 | 38 | window.Draw(box) 39 | 40 | if self.grid[i][j]: 41 | self.grid[i][j].draw(window, x, y) 42 | 43 | def snap(self, window, token): 44 | startx = win_width/2 45 | starty = win_height/2 46 | startx, starty = window.ConvertCoords(startx, starty) 47 | startx -= num_cols * box_width/2 48 | starty -= num_rows * box_height/2 49 | 50 | cx, cy = token.get_center() 51 | cx, cy = int(cx), int(cy) 52 | 53 | 54 | startx, starty = (400, 200) 55 | for i, row in enumerate(self.grid): 56 | y = starty + (i * box_height) 57 | for j, square in enumerate(row): 58 | x = startx + (j * box_width) 59 | 60 | rect = sf.IntRect(x, y, x + box_width, y + box_height) 61 | if not self.grid[i][j] and rect.Contains(cx, cy): 62 | self.grid[i][j] = token 63 | token.i = i 64 | token.j = j 65 | 66 | return 67 | 68 | 69 | def is_end_point(self, node, color): 70 | if color == 'blue' and node[1] == num_cols - 1: 71 | return True 72 | if color == 'red' and node[1] == 0: 73 | return True 74 | return False 75 | 76 | def neighbors(self, root): 77 | right = (root[0] + 1, root[1]) 78 | left = (root[0] - 1, root[1]) 79 | top = (root[0], root[1] + 1) 80 | bottom = (root[0], root[1] - 1) 81 | 82 | neighbors = [] 83 | for node in (right, left, top, bottom): 84 | if node[0] >= 0 and node[1] >= 0 and node[0] <= num_cols - 1 and node[1] <= num_cols - 1 and (not self.grid[node[0]][node[1]] or self.grid[node[0]][node[1]].type != 'rect'): 85 | neighbors.append(node) 86 | 87 | return neighbors 88 | 89 | def find_paths(self, path, color): 90 | paths = [] 91 | if self.is_end_point(path[-1], color): 92 | return path 93 | 94 | for node in self.neighbors(path[-1]): 95 | if not node in path: 96 | path.append(node) 97 | paths += self.find_paths(path, color) 98 | 99 | return paths 100 | 101 | def get_valid_paths(self): 102 | paths = [] 103 | 104 | start = (self.red.i, self.red.j) 105 | 106 | return self.find_paths([start], 'red') 107 | 108 | def find_critical_nodes(self, paths): 109 | if not paths: 110 | return set() 111 | result = set(paths[0]) 112 | for path in paths: 113 | set_path = set(path) 114 | result &= set_path 115 | 116 | return result 117 | 118 | -------------------------------------------------------------------------------- /graph/board.py: -------------------------------------------------------------------------------- 1 | from constants import * 2 | from PySFML import sf 3 | class Board: 4 | def __init__(self, blue, red): 5 | self.grid = [] 6 | self.blue = blue 7 | self.red = red 8 | self.invalid = set() 9 | for i in range(num_rows): 10 | self.grid.append([]) 11 | for j in range(num_cols): 12 | self.grid[i].append(None) 13 | 14 | def draw(self, window): 15 | startx = win_width/2 16 | starty = win_height/2 17 | startx, starty = window.ConvertCoords(startx, starty) 18 | startx -= num_cols * box_width/2 19 | starty -= num_rows * box_height/2 20 | 21 | startx, starty = (400, 200) 22 | for i, row in enumerate(self.grid): 23 | y = starty + (i * box_height) 24 | for j, square in enumerate(row): 25 | x = startx + (j * box_width) 26 | color = sf.Color(255, 255, 255) 27 | if j == 0: 28 | color = red 29 | elif j == num_cols - 1: 30 | color = blue 31 | 32 | bg_color = sf.Color(0, 0, 0) 33 | if (i, j) in self.invalid: 34 | bg_color = sf.Color(150, 25, 25) 35 | 36 | box = sf.Shape.Rectangle(x, y, x + box_width, y + box_height, bg_color, 1, color) 37 | 38 | window.Draw(box) 39 | 40 | if self.grid[i][j]: 41 | self.grid[i][j].draw(window, x, y) 42 | 43 | def snap(self, window, token): 44 | startx = win_width/2 45 | starty = win_height/2 46 | startx, starty = window.ConvertCoords(startx, starty) 47 | startx -= num_cols * box_width/2 48 | starty -= num_rows * box_height/2 49 | 50 | cx, cy = token.get_center() 51 | cx, cy = int(cx), int(cy) 52 | 53 | 54 | startx, starty = (400, 200) 55 | for i, row in enumerate(self.grid): 56 | y = starty + (i * box_height) 57 | for j, square in enumerate(row): 58 | x = startx + (j * box_width) 59 | 60 | rect = sf.IntRect(x, y, x + box_width, y + box_height) 61 | if not self.grid[i][j] and rect.Contains(cx, cy): 62 | self.grid[i][j] = token 63 | if self.valid_paths: 64 | token.i = i 65 | token.j = j 66 | else: 67 | print "YOU BAD" 68 | self.grid[i][j] = None 69 | 70 | return 71 | 72 | 73 | def is_end_point(self, node, color): 74 | if color == 'blue' and node[1] == num_cols - 1: 75 | return True 76 | if color == 'red' and node[1] == 0: 77 | return True 78 | return False 79 | 80 | def neighbors(self, root): 81 | right = (root[0] + 1, root[1]) 82 | left = (root[0] - 1, root[1]) 83 | top = (root[0], root[1] + 1) 84 | bottom = (root[0], root[1] - 1) 85 | 86 | neighbors = [] 87 | for node in (right, left, top, bottom): 88 | if node[0] >= 0 and node[1] >= 0 and node[0] <= num_cols - 1 and node[1] <= num_cols - 1 and (not self.grid[node[0]][node[1]] or self.grid[node[0]][node[1]].type != 'rect'): 89 | neighbors.append(node) 90 | 91 | return neighbors 92 | 93 | def find_paths(self, path, color): 94 | paths = [] 95 | if self.is_end_point(path[-1], color): 96 | return path 97 | 98 | for node in self.neighbors(path[-1]): 99 | if not node in path: 100 | path.append(node) 101 | paths += self.find_paths(path, color) 102 | 103 | return paths 104 | 105 | def get_valid_paths(self): 106 | paths = [] 107 | 108 | start = (self.red.i, self.red.j) 109 | 110 | return self.find_paths([start], 'red') 111 | 112 | def find_critical_nodes(self, paths): 113 | if not paths: 114 | return set() 115 | result = set(paths[0]) 116 | for path in paths: 117 | set_path = set(path) 118 | result &= set_path 119 | 120 | return result 121 | 122 | -------------------------------------------------------------------------------- /old_game.py: -------------------------------------------------------------------------------- 1 | # Include the PySFML extension 2 | from PySFML import sf 3 | import math 4 | import pymunk as pm 5 | 6 | constants = { 7 | 'box_width': 60, 8 | 'box_height': 60, 9 | 'circle_radius': 25, 10 | 'x_boxes': 7, 11 | 'y_boxes': 7, 12 | 'win_width': 1024, 13 | 'win_height': 768 14 | } 15 | 16 | 17 | 18 | # Create the main window 19 | window = sf.RenderWindow(sf.VideoMode(constants['win_width'], constants['win_height']), "PySFML test") 20 | InputHandler = window.GetInput() 21 | 22 | # Create a graphical string to display 23 | text = sf.String("Blockade") 24 | 25 | white = sf.Color(255, 255, 255) 26 | black = sf.Color(0, 0, 0) 27 | red = sf.Color(255, 25, 25) 28 | blue = sf.Color(25, 25, 255) 29 | 30 | grid = [] 31 | for i in range(constants['x_boxes']): 32 | grid.append([]) 33 | for j in range(constants['y_boxes']): 34 | grid[i].append(None) 35 | 36 | def draw_box(window, x, y, color): 37 | width = constants['box_width'] 38 | height = constants['box_height'] 39 | window.Draw(sf.Shape.Rectangle(x, y, x+width, y+height, black, 1, color)) 40 | 41 | def draw_grid(window): 42 | center = (constants['win_width']/2, constants['win_height']/2) 43 | startx = center[0] - constants['x_boxes']*constants['box_width']/2 44 | starty = center[1] - constants['y_boxes']*constants['box_height']/2 45 | for i in range(constants['x_boxes']): 46 | color = white 47 | if i == 0: 48 | color = red 49 | if i == constants['x_boxes'] - 1: 50 | color = blue 51 | 52 | for j in range(constants['y_boxes']): 53 | 54 | draw_box(window, startx + i * constants['box_width'], starty + j * constants['box_height'], color=color) 55 | 56 | """ Returns left/top by default, center if you specify center=True""" 57 | def compute_pos(x, y, center=False): 58 | center = (constants['win_width']/2, constants['win_height']/2) 59 | startx = center[0] - constants['x_boxes']*constants['box_width']/2 60 | starty = center[1] - constants['y_boxes']*constants['box_height']/2 61 | 62 | if center: 63 | startx += constants['box_width']/2 64 | starty += constants['box_height']/2 65 | 66 | return (startx+x * constants['box_width'], starty + y*constants['box_height']) 67 | 68 | 69 | class DraggableCircle: 70 | def __init__(self, color): 71 | self.shape = sf.Shape.Circle(0, 0, constants['circle_radius'], color) 72 | self.dragged = False 73 | self.color = color 74 | self.type = "circle" 75 | 76 | self.grid_pos = [-1, -1] 77 | 78 | def update(self): 79 | if self.grid_pos[0] >= 0 and self.grid_pos[1] >= 0: 80 | pos = compute_pos(*self.grid_pos, center=True) 81 | self.shape.SetPosition(pos[0], pos[1]) 82 | if self.dragged: 83 | self.shape.SetPosition(*window.ConvertCoords(InputHandler.GetMouseX(), InputHandler.GetMouseY())) 84 | 85 | def center(self): 86 | return self.shape.GetPosition() 87 | 88 | def set_center(self, x, y): 89 | self.shape.SetPosition(x, y) 90 | 91 | def mouse_over(self): 92 | x, y = self.center() 93 | 94 | mx = InputHandler.GetMouseX() 95 | my = InputHandler.GetMouseY() 96 | 97 | mx, my = window.ConvertCoords(mx, my) 98 | 99 | return math.sqrt((mx - x) ** 2 + (my - y) ** 2) < constants['circle_radius'] 100 | 101 | class DraggableRect: 102 | def __init__(self, color): 103 | self.color = color 104 | self.dragged = False 105 | self.shape = sf.Shape.Rectangle(0, 0, constants['box_width'], constants['box_height'], color) 106 | self.type = 'rect' 107 | self.grid_pos = [-1, -1] 108 | 109 | def update(self): 110 | if self.grid_pos[0] >= 0 and self.grid_pos[1] >= 0: 111 | pos = compute_pos(*self.grid_pos, center=True) 112 | self.set_center(pos[0], pos[1]) 113 | if self.dragged: 114 | self.shape.SetPosition(*window.ConvertCoords(InputHandler.GetMouseX(), InputHandler.GetMouseY())) 115 | self.shape.Move(-constants['box_width']/2, -constants['box_height']/2) 116 | 117 | def center(self): 118 | x, y = self.shape.GetPosition() 119 | x += constants['box_width']/2 120 | y += constants['box_height']/2 121 | 122 | return (x, y) 123 | 124 | def set_center(self, x, y): 125 | self.shape.SetPosition(x, y) 126 | self.shape.Move(-constants['box_width']/2, -constants['box_height']/2) 127 | 128 | def mouse_over(self): 129 | x, y = self.shape.GetPosition() 130 | x, y = int(x), int(y) 131 | 132 | rect = sf.IntRect(x, y, x + constants['box_width'], y + constants['box_height']) 133 | 134 | mx = InputHandler.GetMouseX() 135 | my = InputHandler.GetMouseY() 136 | 137 | mx, my = window.ConvertCoords(mx, my) 138 | 139 | return rect.Contains(mx, my) 140 | 141 | def get_closest_grid_point(draggable): 142 | for i in range(constants['x_boxes']): 143 | for j in range(constants['y_boxes']): 144 | pos = compute_pos(i, j, False) 145 | 146 | # This represents the grid. 147 | rectangle = sf.IntRect(pos[0], pos[1], pos[0] + constants['box_width'], pos[1] + constants['box_height']) 148 | 149 | if rectangle.Contains(*draggable.center()): 150 | return (i, j) 151 | return None 152 | 153 | 154 | # Start the game loop 155 | 156 | blue_circle = DraggableCircle(blue) 157 | blue_circle.set_center(150, constants['win_height']/2 - 50) 158 | blue_circle.init_position = blue_circle.center() 159 | 160 | red_circle = DraggableCircle(red) 161 | red_circle.set_center(constants['win_width'] - 150, constants['win_height']/2 - 50) 162 | red_circle.init_position = red_circle.center() 163 | 164 | wall = DraggableRect(white) 165 | wall.set_center(constants['win_width'] - 150, constants['win_height'] / 2 + 50) 166 | wall.init_position = wall.center() 167 | 168 | other_wall = DraggableRect(white) 169 | other_wall.set_center(150, constants['win_height'] / 2 + 50) 170 | other_wall.init_position = other_wall.center() 171 | 172 | controls = [red_circle, blue_circle, wall, other_wall] 173 | running = True 174 | 175 | dudes = [] 176 | 177 | red_blockades = 0 178 | blue_blockades = 0 179 | 180 | while running: 181 | event = sf.Event() 182 | while window.GetEvent(event): 183 | if event.Type == sf.Event.Closed: 184 | running = False 185 | if event.Type == sf.Event.MouseButtonPressed: 186 | if event.MouseButton.Button == 0: 187 | for c in controls: 188 | if c.mouse_over(): 189 | c.dragged = True 190 | 191 | for d in dudes: 192 | if d.mouse_over(): 193 | d.dragged = True 194 | else: 195 | for d in dudes: 196 | if d.mouse_over(): 197 | dudes.remove(d) 198 | grid[d.grid_pos[0]][d.grid_pos[1]] = None 199 | 200 | if event.Type == sf.Event.MouseButtonReleased: 201 | for c in controls: 202 | if c.dragged: 203 | closest_point = get_closest_grid_point(c) 204 | if closest_point and not grid[closest_point[0]][closest_point[1]]: 205 | clone = None 206 | if c.type == 'rect': 207 | if c.init_position[0] < constants['win_width']/2: 208 | blue_blockades += 1 209 | else: 210 | red_blockades += 1 211 | clone = DraggableRect(white) 212 | elif c.type == 'circle': 213 | clone = DraggableCircle(c.color) 214 | clone.grid_pos = closest_point 215 | grid[closest_point[0]][closest_point[1]] = clone 216 | clone.update() 217 | clone.init_position = clone.center() 218 | dudes.append(clone) 219 | 220 | c.set_center(*c.init_position) 221 | 222 | c.dragged = False 223 | 224 | for d in dudes: 225 | if d.dragged: 226 | d.dragged = False 227 | closest_point = get_closest_grid_point(d) 228 | if closest_point and not grid[closest_point[0]][closest_point[1]]: 229 | grid[d.grid_pos[0]][d.grid_pos[1]] = None 230 | d.grid_pos = closest_point 231 | grid[closest_point[0]][closest_point[1]] = d 232 | d.update() 233 | d.init_position = d.center() 234 | 235 | else: 236 | d.set_center(*d.init_position) 237 | 238 | 239 | # Clear screen, draw the text, and update the window 240 | window.Clear() 241 | draw_grid(window) 242 | red_blockade_text = sf.String("Blue Blockades %s " % (blue_blockades)) 243 | red_blockade_text.Move(0, 700) 244 | blue_blockade_text = sf.String("Red Blockades %s " % (red_blockades)) 245 | blue_blockade_text.Move(750, 700) 246 | window.Draw(red_blockade_text) 247 | window.Draw(blue_blockade_text) 248 | window.Draw(text) 249 | 250 | for c in controls: 251 | c.update() 252 | window.Draw(c.shape) 253 | 254 | for d in dudes: 255 | d.update() 256 | window.Draw(d.shape) 257 | 258 | window.Display() 259 | -------------------------------------------------------------------------------- /graph/old_game.py: -------------------------------------------------------------------------------- 1 | # Include the PySFML extension 2 | from PySFML import sf 3 | import math 4 | import pymunk as pm 5 | 6 | constants = { 7 | 'box_width': 60, 8 | 'box_height': 60, 9 | 'circle_radius': 25, 10 | 'x_boxes': 7, 11 | 'y_boxes': 7, 12 | 'win_width': 1024, 13 | 'win_height': 768 14 | } 15 | 16 | 17 | 18 | # Create the main window 19 | window = sf.RenderWindow(sf.VideoMode(constants['win_width'], constants['win_height']), "PySFML test") 20 | InputHandler = window.GetInput() 21 | 22 | # Create a graphical string to display 23 | text = sf.String("Blockade") 24 | 25 | white = sf.Color(255, 255, 255) 26 | black = sf.Color(0, 0, 0) 27 | red = sf.Color(255, 25, 25) 28 | blue = sf.Color(25, 25, 255) 29 | 30 | grid = [] 31 | for i in range(constants['x_boxes']): 32 | grid.append([]) 33 | for j in range(constants['y_boxes']): 34 | grid[i].append(None) 35 | 36 | def draw_box(window, x, y, color): 37 | width = constants['box_width'] 38 | height = constants['box_height'] 39 | window.Draw(sf.Shape.Rectangle(x, y, x+width, y+height, black, 1, color)) 40 | 41 | def draw_grid(window): 42 | center = (constants['win_width']/2, constants['win_height']/2) 43 | startx = center[0] - constants['x_boxes']*constants['box_width']/2 44 | starty = center[1] - constants['y_boxes']*constants['box_height']/2 45 | for i in range(constants['x_boxes']): 46 | color = white 47 | if i == 0: 48 | color = red 49 | if i == constants['x_boxes'] - 1: 50 | color = blue 51 | 52 | for j in range(constants['y_boxes']): 53 | 54 | draw_box(window, startx + i * constants['box_width'], starty + j * constants['box_height'], color=color) 55 | 56 | """ Returns left/top by default, center if you specify center=True""" 57 | def compute_pos(x, y, center=False): 58 | center = (constants['win_width']/2, constants['win_height']/2) 59 | startx = center[0] - constants['x_boxes']*constants['box_width']/2 60 | starty = center[1] - constants['y_boxes']*constants['box_height']/2 61 | 62 | if center: 63 | startx += constants['box_width']/2 64 | starty += constants['box_height']/2 65 | 66 | return (startx+x * constants['box_width'], starty + y*constants['box_height']) 67 | 68 | 69 | class DraggableCircle: 70 | def __init__(self, color): 71 | self.shape = sf.Shape.Circle(0, 0, constants['circle_radius'], color) 72 | self.dragged = False 73 | self.color = color 74 | self.type = "circle" 75 | 76 | self.grid_pos = [-1, -1] 77 | 78 | def update(self): 79 | if self.grid_pos[0] >= 0 and self.grid_pos[1] >= 0: 80 | pos = compute_pos(*self.grid_pos, center=True) 81 | self.shape.SetPosition(pos[0], pos[1]) 82 | if self.dragged: 83 | self.shape.SetPosition(*window.ConvertCoords(InputHandler.GetMouseX(), InputHandler.GetMouseY())) 84 | 85 | def center(self): 86 | return self.shape.GetPosition() 87 | 88 | def set_center(self, x, y): 89 | self.shape.SetPosition(x, y) 90 | 91 | def mouse_over(self): 92 | x, y = self.center() 93 | 94 | mx = InputHandler.GetMouseX() 95 | my = InputHandler.GetMouseY() 96 | 97 | mx, my = window.ConvertCoords(mx, my) 98 | 99 | return math.sqrt((mx - x) ** 2 + (my - y) ** 2) < constants['circle_radius'] 100 | 101 | class DraggableRect: 102 | def __init__(self, color): 103 | self.color = color 104 | self.dragged = False 105 | self.shape = sf.Shape.Rectangle(0, 0, constants['box_width'], constants['box_height'], color) 106 | self.type = 'rect' 107 | self.grid_pos = [-1, -1] 108 | 109 | def update(self): 110 | if self.grid_pos[0] >= 0 and self.grid_pos[1] >= 0: 111 | pos = compute_pos(*self.grid_pos, center=True) 112 | self.set_center(pos[0], pos[1]) 113 | if self.dragged: 114 | self.shape.SetPosition(*window.ConvertCoords(InputHandler.GetMouseX(), InputHandler.GetMouseY())) 115 | self.shape.Move(-constants['box_width']/2, -constants['box_height']/2) 116 | 117 | def center(self): 118 | x, y = self.shape.GetPosition() 119 | x += constants['box_width']/2 120 | y += constants['box_height']/2 121 | 122 | return (x, y) 123 | 124 | def set_center(self, x, y): 125 | self.shape.SetPosition(x, y) 126 | self.shape.Move(-constants['box_width']/2, -constants['box_height']/2) 127 | 128 | def mouse_over(self): 129 | x, y = self.shape.GetPosition() 130 | x, y = int(x), int(y) 131 | 132 | rect = sf.IntRect(x, y, x + constants['box_width'], y + constants['box_height']) 133 | 134 | mx = InputHandler.GetMouseX() 135 | my = InputHandler.GetMouseY() 136 | 137 | mx, my = window.ConvertCoords(mx, my) 138 | 139 | return rect.Contains(mx, my) 140 | 141 | def get_closest_grid_point(draggable): 142 | for i in range(constants['x_boxes']): 143 | for j in range(constants['y_boxes']): 144 | pos = compute_pos(i, j, False) 145 | 146 | # This represents the grid. 147 | rectangle = sf.IntRect(pos[0], pos[1], pos[0] + constants['box_width'], pos[1] + constants['box_height']) 148 | 149 | if rectangle.Contains(*draggable.center()): 150 | return (i, j) 151 | return None 152 | 153 | 154 | # Start the game loop 155 | 156 | blue_circle = DraggableCircle(blue) 157 | blue_circle.set_center(150, constants['win_height']/2 - 50) 158 | blue_circle.init_position = blue_circle.center() 159 | 160 | red_circle = DraggableCircle(red) 161 | red_circle.set_center(constants['win_width'] - 150, constants['win_height']/2 - 50) 162 | red_circle.init_position = red_circle.center() 163 | 164 | wall = DraggableRect(white) 165 | wall.set_center(constants['win_width'] - 150, constants['win_height'] / 2 + 50) 166 | wall.init_position = wall.center() 167 | 168 | other_wall = DraggableRect(white) 169 | other_wall.set_center(150, constants['win_height'] / 2 + 50) 170 | other_wall.init_position = other_wall.center() 171 | 172 | controls = [red_circle, blue_circle, wall, other_wall] 173 | running = True 174 | 175 | dudes = [] 176 | 177 | red_blockades = 0 178 | blue_blockades = 0 179 | 180 | while running: 181 | event = sf.Event() 182 | while window.GetEvent(event): 183 | if event.Type == sf.Event.Closed: 184 | running = False 185 | if event.Type == sf.Event.MouseButtonPressed: 186 | if event.MouseButton.Button == 0: 187 | for c in controls: 188 | if c.mouse_over(): 189 | c.dragged = True 190 | 191 | for d in dudes: 192 | if d.mouse_over(): 193 | d.dragged = True 194 | else: 195 | for d in dudes: 196 | if d.mouse_over(): 197 | dudes.remove(d) 198 | grid[d.grid_pos[0]][d.grid_pos[1]] = None 199 | 200 | if event.Type == sf.Event.MouseButtonReleased: 201 | for c in controls: 202 | if c.dragged: 203 | closest_point = get_closest_grid_point(c) 204 | if closest_point and not grid[closest_point[0]][closest_point[1]]: 205 | clone = None 206 | if c.type == 'rect': 207 | if c.init_position[0] < constants['win_width']/2: 208 | blue_blockades += 1 209 | else: 210 | red_blockades += 1 211 | clone = DraggableRect(white) 212 | elif c.type == 'circle': 213 | clone = DraggableCircle(c.color) 214 | clone.grid_pos = closest_point 215 | grid[closest_point[0]][closest_point[1]] = clone 216 | clone.update() 217 | clone.init_position = clone.center() 218 | dudes.append(clone) 219 | 220 | c.set_center(*c.init_position) 221 | 222 | c.dragged = False 223 | 224 | for d in dudes: 225 | if d.dragged: 226 | d.dragged = False 227 | closest_point = get_closest_grid_point(d) 228 | if closest_point and not grid[closest_point[0]][closest_point[1]]: 229 | grid[d.grid_pos[0]][d.grid_pos[1]] = None 230 | d.grid_pos = closest_point 231 | grid[closest_point[0]][closest_point[1]] = d 232 | d.update() 233 | d.init_position = d.center() 234 | 235 | else: 236 | d.set_center(*d.init_position) 237 | 238 | 239 | # Clear screen, draw the text, and update the window 240 | window.Clear() 241 | draw_grid(window) 242 | red_blockade_text = sf.String("Blue Blockades %s " % (blue_blockades)) 243 | red_blockade_text.Move(0, 700) 244 | blue_blockade_text = sf.String("Red Blockades %s " % (red_blockades)) 245 | blue_blockade_text.Move(750, 700) 246 | window.Draw(red_blockade_text) 247 | window.Draw(blue_blockade_text) 248 | window.Draw(text) 249 | 250 | for c in controls: 251 | c.update() 252 | window.Draw(c.shape) 253 | 254 | for d in dudes: 255 | d.update() 256 | window.Draw(d.shape) 257 | 258 | window.Display() 259 | --------------------------------------------------------------------------------