Created
April 3, 2024 21:23
-
-
Save jtemporal/d9055d7fc855b8c0278ff00a5c5bc620 to your computer and use it in GitHub Desktop.
Updated tic tac toe from https://www.youtube.com/watch?v=jPWTEd9F2QY
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 time, math | |
import badger2040 | |
import badger_os | |
# Global Constants | |
WIDTH = badger2040.WIDTH | |
HEIGHT = badger2040.HEIGHT | |
# Tic-Tac-Toe / Noughts and Crosses game | |
# Grid is x,y | |
# x is 0 to 2 (left to right) | |
# y is 0 to 2 (top to bottom) | |
def draw(): | |
display.set_pen(15) | |
display.clear() | |
# Show grid | |
display.set_pen(0) | |
display.set_thickness(2) | |
display.line(103, 49, 193, 49) | |
display.line(103, 79, 193, 79) | |
display.line(133, 19, 133, 109) | |
display.line(163, 19, 163, 109) | |
# draw any played positions | |
for gy in range (0, 3): | |
for gx in range (0, 3): | |
if (grid[gx][gy] == 0): | |
# draw a cross | |
draw_cross(gx, gy) | |
elif (grid[gx][gy] == 1): | |
# draw a nought | |
draw_nought(gx, gy) | |
# Only show player and cursor if in game | |
if state == "play": | |
# Show current player | |
display.text("Player", 20, 20, 1) | |
if (player == 0): | |
draw_x (40, 50) | |
elif (player == 1): | |
draw_circle (40, 50) | |
draw_cursor(*cursor) | |
if state == "gameover": | |
display.text ("Game Over", 10, 10, 1) | |
# If there is a winner show the line | |
winner = is_won() | |
if winner >= 0: | |
# Draw line | |
display.line(*winning_line) | |
display.text("Winner", 15, 40, 1) | |
if winner == 0: | |
draw_x (40, 70) | |
if winner == 1: | |
draw_circle (40, 70) | |
# It's a draw | |
else: | |
display.text ("Draw", 10, 40, 1) | |
# Draw the noughts and crosses | |
# Top level - draw nought on grid | |
def draw_nought(gridx, gridy): | |
# Approximation of a circle using lines | |
# get centre of circle | |
(cx, cy) = grid_to_coord(gridx, gridy) | |
draw_circle (cx, cy) | |
# Lower level needs co-ords - useful for player scores etc. | |
def draw_circle(cx, cy, radius=10): | |
degree_step_size = 10 | |
# build list of points | |
points = [] | |
for i in range (0, 360, degree_step_size): | |
irad = math.radians(i) | |
this_x = int(cx + radius * math.cos(irad)) | |
this_y = int(cy + radius * math.sin(irad)) | |
points.append ((this_x, this_y)) | |
for i in range(len(points)-1): | |
display.line (*points[i], *points[i+1]) | |
# final back to the start | |
display.line(*points[len(points)-1], *points[0]) | |
# High level - draw cross on grid | |
def draw_cross(gridx, gridy): | |
# get centre of cross | |
(cx, cy) = grid_to_coord(gridx, gridy) | |
draw_x (cx, cy) | |
# Lower level needs co-ords - useful for player scores etc. | |
def draw_x (cx, cy): | |
display.line (cx -10, cy -10, cx + 10, cy + 10) | |
display.line (cx +10, cy -10, cx - 10, cy + 10) | |
def draw_cursor(gridx, gridy): | |
# draw square | |
(cx, cy) = grid_to_coord(gridx, gridy) | |
display.rectangle (cx -4, cy -4, 8, 8) | |
# ------------------------------ | |
# Helper methods | |
# ------------------------------ | |
# Convert x,y position to centre of square | |
def grid_to_coord (gridx, gridy): | |
x = 118 + 30 * gridx | |
y = 34 + 30 * gridy | |
return (x, y) | |
# Checks for possible wins | |
def is_won (): | |
global willing_line | |
# start with first square on a possible line, check that has a player assigned | |
# then check rest of that line matches - if so then return the first square value | |
# which will equal the player number. If not return -1 | |
# Check vertical lines | |
for col in range (0, 3): | |
if grid[col][0] != -1 and grid[col][0] == grid[col][1] and grid[col][1] == grid[col][2]: | |
winning_line[0] = 118 + col * 30 | |
winning_line[1] = 19 | |
winning_line[2] = 118 + col * 30 | |
winning_line[3] = 109 | |
return grid[col][0] | |
# Check horizontal lines | |
for line in range (0, 3): | |
if grid[0][line] != -1 and grid[0][line] == grid[1][line] and grid[1][line] == grid[2][line]: | |
winning_line[0] = 103 | |
winning_line[1] = 34 + line * 30 | |
winning_line[2] = 193 | |
winning_line[3] = 34 + line * 30 | |
return grid[0][line] | |
# check 2 diagnals | |
if grid[0][0] != -1 and grid[0][0] == grid[1][1] and grid[1][1] == grid[2][2]: | |
winning_line[0] = 103 | |
winning_line[1] = 19 | |
winning_line[2] = 193 | |
winning_line[3] = 109 | |
return grid[0][0] | |
if grid[2][0] != -1 and grid[2][0] == grid[1][1] and grid[1][1] == grid[0][2]: | |
winning_line[0] = 193 | |
winning_line[1] = 19 | |
winning_line[2] = 103 | |
winning_line[3] = 109 | |
return grid[2][0] | |
# reach here no match | |
return -1 | |
# ------------------------------ | |
# Program setup | |
# ------------------------------ | |
# Create a new Badger and set it to update NORMAL | |
display = badger2040.Badger2040() | |
display.led(128) | |
# ------------------------------ | |
# Main program | |
# ------------------------------ | |
state = "play" | |
# Player 0 = crosses (goes first on first game) | |
# Player 1 = noughts | |
player = 0 | |
cursor = [0,0] | |
# number of goes played - when reach 9 know that grid is full | |
played = 0 | |
# Grid is x y (cols then rows) - so array does not look the same | |
# -1 = none | |
# 0 = player 0 | |
# 1 = player 1 | |
grid = [ | |
[-1,-1, -1], | |
[-1,-1,-1], | |
[-1,-1,-1]] | |
# winning_line used as a global to determine where to draw line when someone wins | |
winning_line = [0,0,0,0] | |
# Display initial screen | |
draw() | |
display.update() | |
while (1): | |
# wait for action (uses loop) | |
while (1): | |
if state == "play": | |
display.set_update_speed(badger2040.UPDATE_TURBO) | |
if display.pressed(badger2040.BUTTON_A): | |
if cursor[0] > 0: | |
cursor[0] -= 1 | |
break | |
if display.pressed(badger2040.BUTTON_C): | |
if cursor[0] < 2: | |
cursor[0] += 1 | |
break | |
if display.pressed(badger2040.BUTTON_UP): | |
if cursor[1] > 0: | |
cursor[1] -= 1 | |
break | |
if display.pressed(badger2040.BUTTON_DOWN): | |
if cursor[1] < 2: | |
cursor[1] += 1 | |
break | |
if display.pressed(badger2040.BUTTON_B): | |
display.set_update_speed(badger2040.UPDATE_MEDIUM) | |
# If empty then place the mark | |
# If not empty then ignore button press | |
if (grid[cursor[0]][cursor[1]] == -1): | |
grid[cursor[0]][cursor[1]] = player | |
played += 1 | |
# Swap player and reset cursor | |
if player == 0: | |
player = 1 | |
else: | |
player = 0 | |
# return cursor to top left | |
cursor[0] = 0 | |
cursor[1] = 0 | |
break | |
# Otherwise press B to start game | |
else: | |
if display.pressed(badger2040.BUTTON_B): | |
state == "play" | |
if is_won() >= 0 or played >= 9: | |
state = "gameover" | |
draw() | |
display.update() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment