User prompt
import tkinter as tk
import random
CELL_SIZE = 30
GRID_COLS = 20
GRID_ROWS = 15
WINDOW_WIDTH = CELL_SIZE * GRID_COLS
WINDOW_HEIGHT = CELL_SIZE * GRID_ROWS
root = tk.Tk()
root.title("Blue Head Tail Game with Border Collision")
root.geometry(f"{WINDOW_WIDTH}x{WINDOW_HEIGHT}")
canvas = tk.Canvas(root, width=WINDOW_WIDTH, height=WINDOW_HEIGHT, bg="white")
canvas.pack()
# Draw grid lines
for i in range(GRID_COLS + 1):
canvas.create_line(i * CELL_SIZE, 0, i * CELL_SIZE, WINDOW_HEIGHT, fill="lightgray")
for j in range(GRID_ROWS + 1):
canvas.create_line(0, j * CELL_SIZE, WINDOW_WIDTH, j * CELL_SIZE, fill="lightgray")
# Initial position of the blue head
head_col, head_row = 5, 5
head = canvas.create_rectangle(
head_col * CELL_SIZE,
head_row * CELL_SIZE,
(head_col + 1) * CELL_SIZE,
(head_row + 1) * CELL_SIZE,
fill="blue"
)
tail_positions = []
tail_rects = []
score = 0
score_text = canvas.create_text(10, 10, anchor="nw", font=("Arial", 16), text="Score: 0", fill="blue")
def spawn_red_box():
while True:
# Red box sirf border ke andar ke cells me spawn hoga
red_col = random.randint(1, GRID_COLS - 2)
red_row = random.randint(1, GRID_ROWS - 2)
if (red_col, red_row) != (head_col, head_row) and (red_col, red_row) not in tail_positions:
break
return canvas.create_rectangle(
red_col * CELL_SIZE,
red_row * CELL_SIZE,
(red_col + 1) * CELL_SIZE,
(red_row + 1) * CELL_SIZE,
fill="red"
), red_col, red_row
red_box, red_col, red_row = spawn_red_box()
# Game Over overlay items (hidden initially)
game_over_rect = canvas.create_rectangle(50, 100, WINDOW_WIDTH - 50, WINDOW_HEIGHT - 100, fill='black', stipple='gray50', state='hidden')
game_over_text = canvas.create_text(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2 - 40, text="GAME OVER", fill="white", font=("Arial", 40, "bold"), state='hidden')
retry_button_rect = canvas.create_rectangle(WINDOW_WIDTH//2 - 60, WINDOW_HEIGHT//2 + 10, WINDOW_WIDTH//2 + 60, WINDOW_HEIGHT//2 + 60, fill="blue", state='hidden')
retry_button_text = canvas.create_text(WINDOW_WIDTH//2, WINDOW_HEIGHT//2 + 35, text="RETRY", fill="white", font=("Arial", 20, "bold"), state='hidden')
game_running = True
def show_game_over():
global game_running
game_running = False
canvas.itemconfigure(game_over_rect, state='normal')
canvas.itemconfigure(game_over_text, state='normal')
canvas.itemconfigure(retry_button_rect, state='normal')
canvas.itemconfigure(retry_button_text, state='normal')
def hide_game_over():
canvas.itemconfigure(game_over_rect, state='hidden')
canvas.itemconfigure(game_over_text, state='hidden')
canvas.itemconfigure(retry_button_rect, state='hidden')
canvas.itemconfigure(retry_button_text, state='hidden')
def reset_game():
global head_col, head_row, score, tail_positions, tail_rects, red_box, red_col, red_row, game_running
head_col, head_row = 5, 5
score = 0
canvas.itemconfig(score_text, text="Score: 0")
canvas.coords(
head,
head_col * CELL_SIZE,
head_row * CELL_SIZE,
(head_col + 1) * CELL_SIZE,
(head_row + 1) * CELL_SIZE
)
for rect in tail_rects:
canvas.delete(rect)
tail_positions.clear()
tail_rects.clear()
canvas.delete(red_box)
red_box, red_col, red_row = spawn_red_box()
hide_game_over()
game_running = True
def on_canvas_click(event):
if not game_running:
# Check if click inside retry button rectangle
x1, y1, x2, y2 = canvas.coords(retry_button_rect)
if x1 <= event.x <= x2 and y1 <= event.y <= y2:
reset_game()
def move(event):
global head_col, head_row, red_box, red_col, red_row, score
if not game_running:
return
prev_positions = [(head_col, head_row)] + tail_positions[:-1]
if event.keysym == 'Left' and head_col > 0:
head_col -= 1
elif event.keysym == 'Right' and head_col < GRID_COLS - 1:
head_col += 1
elif event.keysym == 'Up' and head_row > 0:
head_row -= 1
elif event.keysym == 'Down' and head_row < GRID_ROWS - 1:
head_row += 1
else:
return
# Agar blue head kisi bhi border pe aa gaya to game over
if head_col == 0 or head_col == GRID_COLS - 1 or head_row == 0 or head_row == GRID_ROWS - 1:
show_game_over()
return
# Agar blue head apne tail se takra gaya to game over
if (head_col, head_row) in tail_positions:
show_game_over()
return
# Move head rectangle
canvas.coords(
head,
head_col * CELL_SIZE,
head_row * CELL_SIZE,
(head_col + 1) * CELL_SIZE,
(head_row + 1) * CELL_SIZE
)
# Move tail rectangles to previous positions
for i in range(len(tail_positions)):
tail_positions[i] = prev_positions[i]
col, row = tail_positions[i]
canvas.coords(
tail_rects[i],
col * CELL_SIZE,
row * CELL_SIZE,
(col + 1) * CELL_SIZE,
(row + 1) * CELL_SIZE
)
# Check if blue head collected red box
if head_col == red_col and head_row == red_row:
canvas.delete(red_box)
score += 1
canvas.itemconfig(score_text, text=f"Score: {score}")
if tail_positions:
last_col, last_row = tail_positions[-1]
else:
last_col, last_row = prev_positions[0]
# Add new tail segment behind last tail or head
tail_positions.append((last_col, last_row))
new_tail = canvas.create_rectangle(
last_col * CELL_SIZE,
last_row * CELL_SIZE,
(last_col + 1) * CELL_SIZE,
(last_row + 1) * CELL_SIZE,
fill="black"
)
tail_rects.append(new_tail)
# Spawn new red box randomly
red_box, red_col, red_row = spawn_red_box()
root.bind("
User prompt
/**** * Assets ****/ LK.init.shape('food', {width:40, height:40, color:0xff0000, shape:'box'}); LK.init.shape('gridBorder', {width:40, height:40, color:0x666666, shape:'box'}); LK.init.shape('snakeHead', {width:40, height:40, color:0x4285f4, shape:'box'}); LK.init.shape('snakeTail', {width:40, height:40, color:0x000000, shape:'box'}); LK.init.sound('eat'); LK.init.sound('gameOver'); /**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Food = Container.expand(function () { var self = Container.call(this); var foodGraphics = self.attachAsset('food', { anchorX: 0.5, anchorY: 0.5 }); return self; }); var GridBorder = Container.expand(function () { var self = Container.call(this); var borderGraphics = self.attachAsset('gridBorder', { anchorX: 0.5, anchorY: 0.5 }); return self; }); var SnakeHead = Container.expand(function () { var self = Container.call(this); var headGraphics = self.attachAsset('snakeHead', { anchorX: 0.5, anchorY: 0.5 }); return self; }); var SnakeTail = Container.expand(function () { var self = Container.call(this); var tailGraphics = self.attachAsset('snakeTail', { anchorX: 0.5, anchorY: 0.5 }); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2d5016 }); /**** * Game Code ****/ // Grid configuration var gridSize = 40; var gridWidth = 20; var gridHeight = 25; var gameAreaWidth = gridWidth * gridSize; var gameAreaHeight = gridHeight * gridSize; var offsetX = (2048 - gameAreaWidth) / 2; var offsetY = (2732 - gameAreaHeight) / 2 - 200; // Snake variables var snake = []; var direction = { x: 1, y: 0 }; var nextDirection = { x: 1, y: 0 }; var food = null; var gameRunning = false; var moveTimer = 0; var moveInterval = 200; // Create border walls var borders = []; for (var x = -1; x <= gridWidth; x++) { for (var y = -1; y <= gridHeight; y++) { if (x === -1 || x === gridWidth || y === -1 || y === gridHeight) { var border = new GridBorder(); border.x = offsetX + x * gridSize + gridSize / 2; border.y = offsetY + y * gridSize + gridSize / 2; borders.push(border); game.addChild(border); } } } // Create score display var scoreTxt = new Text2('Score: 0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); scoreTxt.y = 50; // Initialize snake function initializeSnake() { for (var i = 0; i < snake.length; i++) { snake[i].destroy(); } snake = []; var head = new SnakeHead(); head.gridX = Math.floor(gridWidth / 2); head.gridY = Math.floor(gridHeight / 2); head.x = offsetX + head.gridX * gridSize + gridSize / 2; head.y = offsetY + head.gridY * gridSize + gridSize / 2; snake.push(head); game.addChild(head); for (var i = 1; i < 3; i++) { var tail = new SnakeTail(); tail.gridX = head.gridX - i; tail.gridY = head.gridY; tail.x = offsetX + tail.gridX * gridSize + gridSize / 2; tail.y = offsetY + tail.gridY * gridSize + gridSize / 2; snake.push(tail); game.addChild(tail); } direction = { x: 1, y: 0 }; nextDirection = { x: 1, y: 0 }; gameRunning = true; LK.setScore(0); scoreTxt.setText("Score: 0"); spawnFood(); } function spawnFood() { if (food) food.destroy(); var validPositions = []; for (var x = 0; x < gridWidth; x++) { for (var y = 0; y < gridHeight; y++) { var occupied = false; for (var i = 0; i < snake.length; i++) { if (snake[i].gridX === x && snake[i].gridY === y) { occupied = true; break; } } if (!occupied) validPositions.push({ x: x, y: y }); } } if (validPositions.length > 0) { var randomPos = validPositions[Math.floor(Math.random() * validPositions.length)]; food = new Food(); food.gridX = randomPos.x; food.gridY = randomPos.y; food.x = offsetX + food.gridX * gridSize + gridSize / 2; food.y = offsetY + food.gridY * gridSize + gridSize / 2; game.addChild(food); } } function moveSnake() { if (!gameRunning) return; direction = nextDirection; var head = snake[0]; var newX = head.gridX + direction.x; var newY = head.gridY + direction.y; // Collision with walls if (newX < 0 || newX >= gridWidth || newY < 0 || newY >= gridHeight) { gameOver(); return; } // Collision with self for (var i = 1; i < snake.length; i++) { if (snake[i].gridX === newX && snake[i].gridY === newY) { gameOver(); return; } } // Check food var ateFood = false; if (food && food.gridX === newX && food.gridY === newY) { ateFood = true; LK.setScore(LK.getScore() + 1); scoreTxt.setText("Score: " + LK.getScore()); LK.getSound('eat').play(); var lastTail = snake[snake.length - 1]; var newTail = new SnakeTail(); newTail.gridX = lastTail.gridX; newTail.gridY = lastTail.gridY; newTail.x = offsetX + newTail.gridX * gridSize + gridSize / 2; newTail.y = offsetY + newTail.gridY * gridSize + gridSize / 2; snake.push(newTail); game.addChild(newTail); spawnFood(); } // Move body for (var i = snake.length - 1; i > 0; i--) { snake[i].gridX = snake[i - 1].gridX; snake[i].gridY = snake[i - 1].gridY; snake[i].x = offsetX + snake[i].gridX * gridSize + gridSize / 2; snake[i].y = offsetY + snake[i].gridY * gridSize + gridSize / 2; } // Move head head.gridX = newX; head.gridY = newY; head.x = offsetX + head.gridX * gridSize + gridSize / 2; head.y = offsetY + head.gridY * gridSize + gridSize / 2; } function gameOver() { gameRunning = false; LK.getSound('gameOver').play(); LK.effects.flashScreen(0xff0000, 500); LK.setTimeout(function () { LK.showGameOver(initializeSnake); }, 500); } // Touch controls var startTouchX = 0; var startTouchY = 0; var touchStarted = false; game.down = function (x, y, obj) { if (!gameRunning) return; startTouchX = x; startTouchY = y; touchStarted = true; }; game.up = function (x, y, obj) { if (!gameRunning || !touchStarted) return; touchStarted = false; var deltaX = x - startTouchX; var deltaY = y - startTouchY; var minSwipeDistance = 50; if (Math.abs(deltaX) > Math.abs(deltaY)) { if (Math.abs(deltaX ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Snake Grid Master
Initial prompt
import tkinter as tk
import random
CELL_SIZE = 30
GRID_COLS = 20
GRID_ROWS = 15
WINDOW_WIDTH = CELL_SIZE * GRID_COLS
WINDOW_HEIGHT = CELL_SIZE * GRID_ROWS
root = tk.Tk()
root.title("Blue Head Tail Game with Border Collision")
root.geometry(f"{WINDOW_WIDTH}x{WINDOW_HEIGHT}")
canvas = tk.Canvas(root, width=WINDOW_WIDTH, height=WINDOW_HEIGHT, bg="white")
canvas.pack()
# Draw grid lines
for i in range(GRID_COLS + 1):
canvas.create_line(i * CELL_SIZE, 0, i * CELL_SIZE, WINDOW_HEIGHT, fill="lightgray")
for j in range(GRID_ROWS + 1):
canvas.create_line(0, j * CELL_SIZE, WINDOW_WIDTH, j * CELL_SIZE, fill="lightgray")
# Initial position of the blue head
head_col, head_row = 5, 5
head = canvas.create_rectangle(
head_col * CELL_SIZE,
head_row * CELL_SIZE,
(head_col + 1) * CELL_SIZE,
(head_row + 1) * CELL_SIZE,
fill="blue"
)
tail_positions = []
tail_rects = []
score = 0
score_text = canvas.create_text(10, 10, anchor="nw", font=("Arial", 16), text="Score: 0", fill="blue")
def spawn_red_box():
while True:
# Red box sirf border ke andar ke cells me spawn hoga
red_col = random.randint(1, GRID_COLS - 2)
red_row = random.randint(1, GRID_ROWS - 2)
if (red_col, red_row) != (head_col, head_row) and (red_col, red_row) not in tail_positions:
break
return canvas.create_rectangle(
red_col * CELL_SIZE,
red_row * CELL_SIZE,
(red_col + 1) * CELL_SIZE,
(red_row + 1) * CELL_SIZE,
fill="red"
), red_col, red_row
red_box, red_col, red_row = spawn_red_box()
# Game Over overlay items (hidden initially)
game_over_rect = canvas.create_rectangle(50, 100, WINDOW_WIDTH - 50, WINDOW_HEIGHT - 100, fill='black', stipple='gray50', state='hidden')
game_over_text = canvas.create_text(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2 - 40, text="GAME OVER", fill="white", font=("Arial", 40, "bold"), state='hidden')
retry_button_rect = canvas.create_rectangle(WINDOW_WIDTH//2 - 60, WINDOW_HEIGHT//2 + 10, WINDOW_WIDTH//2 + 60, WINDOW_HEIGHT//2 + 60, fill="blue", state='hidden')
retry_button_text = canvas.create_text(WINDOW_WIDTH//2, WINDOW_HEIGHT//2 + 35, text="RETRY", fill="white", font=("Arial", 20, "bold"), state='hidden')
game_running = True
def show_game_over():
global game_running
game_running = False
canvas.itemconfigure(game_over_rect, state='normal')
canvas.itemconfigure(game_over_text, state='normal')
canvas.itemconfigure(retry_button_rect, state='normal')
canvas.itemconfigure(retry_button_text, state='normal')
def hide_game_over():
canvas.itemconfigure(game_over_rect, state='hidden')
canvas.itemconfigure(game_over_text, state='hidden')
canvas.itemconfigure(retry_button_rect, state='hidden')
canvas.itemconfigure(retry_button_text, state='hidden')
def reset_game():
global head_col, head_row, score, tail_positions, tail_rects, red_box, red_col, red_row, game_running
head_col, head_row = 5, 5
score = 0
canvas.itemconfig(score_text, text="Score: 0")
canvas.coords(
head,
head_col * CELL_SIZE,
head_row * CELL_SIZE,
(head_col + 1) * CELL_SIZE,
(head_row + 1) * CELL_SIZE
)
for rect in tail_rects:
canvas.delete(rect)
tail_positions.clear()
tail_rects.clear()
canvas.delete(red_box)
red_box, red_col, red_row = spawn_red_box()
hide_game_over()
game_running = True
def on_canvas_click(event):
if not game_running:
# Check if click inside retry button rectangle
x1, y1, x2, y2 = canvas.coords(retry_button_rect)
if x1 <= event.x <= x2 and y1 <= event.y <= y2:
reset_game()
def move(event):
global head_col, head_row, red_box, red_col, red_row, score
if not game_running:
return
prev_positions = [(head_col, head_row)] + tail_positions[:-1]
if event.keysym == 'Left' and head_col > 0:
head_col -= 1
elif event.keysym == 'Right' and head_col < GRID_COLS - 1:
head_col += 1
elif event.keysym == 'Up' and head_row > 0:
head_row -= 1
elif event.keysym == 'Down' and head_row < GRID_ROWS - 1:
head_row += 1
else:
return
# Agar blue head kisi bhi border pe aa gaya to game over
if head_col == 0 or head_col == GRID_COLS - 1 or head_row == 0 or head_row == GRID_ROWS - 1:
show_game_over()
return
# Agar blue head apne tail se takra gaya to game over
if (head_col, head_row) in tail_positions:
show_game_over()
return
# Move head rectangle
canvas.coords(
head,
head_col * CELL_SIZE,
head_row * CELL_SIZE,
(head_col + 1) * CELL_SIZE,
(head_row + 1) * CELL_SIZE
)
# Move tail rectangles to previous positions
for i in range(len(tail_positions)):
tail_positions[i] = prev_positions[i]
col, row = tail_positions[i]
canvas.coords(
tail_rects[i],
col * CELL_SIZE,
row * CELL_SIZE,
(col + 1) * CELL_SIZE,
(row + 1) * CELL_SIZE
)
# Check if blue head collected red box
if head_col == red_col and head_row == red_row:
canvas.delete(red_box)
score += 1
canvas.itemconfig(score_text, text=f"Score: {score}")
if tail_positions:
last_col, last_row = tail_positions[-1]
else:
last_col, last_row = prev_positions[0]
# Add new tail segment behind last tail or head
tail_positions.append((last_col, last_row))
new_tail = canvas.create_rectangle(
last_col * CELL_SIZE,
last_row * CELL_SIZE,
(last_col + 1) * CELL_SIZE,
(last_row + 1) * CELL_SIZE,
fill="black"
)
tail_rects.append(new_tail)
# Spawn new red box randomly
red_box, red_col, red_row = spawn_red_box()
root.bind("
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
}); /****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});