juegos-python/Chain_Reaction/Chain-Reaction.py
2023-04-10 00:48:44 +02:00

257 lines
7.3 KiB
Python

# -----------------------------------------------------------------------------
#
# Chain Reaction
# Language - Python
# Modules - pygame, sys, math
#
# Controls - Mouse Click
#
# By - Jatin Kumar Mandav
#
# Website - https://jatinmandav.wordpress.com
#
# YouTube Channel - https://www.youtube.com/channel/UCdpf6Lz3V357cIZomPwjuFQ
# Twitter - @jatinmandav
#
# -----------------------------------------------------------------------------
import pygame
import sys
from math import *
# Initialization of Pygame
pygame.init()
width = 400
height = 400
display = pygame.display.set_mode((width, height))
clock = pygame.time.Clock()
# Colors
background = (21, 67, 96)
border = (208, 211, 212)
red = (231, 76, 60)
white = (244, 246, 247)
violet = (136, 78, 160)
yellow = (244, 208, 63)
green = (88, 214, 141)
playerColor = [red, green, violet, yellow]
font = pygame.font.SysFont("Times New Roman", 30)
blocks = 40
noPlayers = 4
pygame.display.set_caption("Chain Reaction %d Player" % noPlayers)
score = []
for i in range(noPlayers):
score.append(0)
players = []
for i in range(noPlayers):
players.append(playerColor[i])
d = blocks//2 - 2
cols = int(width//blocks)
rows = int(height//blocks)
grid = []
# Quit or Close the Game Window
def close():
pygame.quit()
sys.exit()
# Class for Each Spot in Grid
class Spot():
def __init__(self):
self.color = border
self.neighbors = []
self.noAtoms = 0
def addNeighbors(self, i, j):
if i > 0:
self.neighbors.append(grid[i - 1][j])
if i < rows - 1:
self.neighbors.append(grid[i + 1][j])
if j < cols - 1:
self.neighbors.append(grid[i][j + 1])
if j > 0:
self.neighbors.append(grid[i][j - 1])
# Initializing the Grid with "Empty or 0"
def initializeGrid():
global grid, score, players
score = []
for i in range(noPlayers):
score.append(0)
players = []
for i in range(noPlayers):
players.append(playerColor[i])
grid = [[]for _ in range(cols)]
for i in range(cols):
for j in range(rows):
newObj = Spot()
grid[i].append(newObj)
for i in range(cols):
for j in range(rows):
grid[i][j].addNeighbors(i, j)
# Draw the Grid in Pygame Window
def drawGrid(currentIndex):
r = 0
c = 0
for i in range(width//blocks):
r += blocks
c += blocks
pygame.draw.line(display, players[currentIndex], (c, 0), (c, height))
pygame.draw.line(display, players[currentIndex], (0, r), (width, r))
# Draw the Present Situation of Grid
def showPresentGrid(vibrate = 1):
r = -blocks
c = -blocks
padding = 2
for i in range(cols):
r += blocks
c = -blocks
for j in range(rows):
c += blocks
if grid[i][j].noAtoms == 0:
grid[i][j].color = border
elif grid[i][j].noAtoms == 1:
pygame.draw.ellipse(display, grid[i][j].color, (r + blocks/2 - d/2 + vibrate, c + blocks/2 - d/2, d, d))
elif grid[i][j].noAtoms == 2:
pygame.draw.ellipse(display, grid[i][j].color, (r + 5, c + blocks/2 - d/2 - vibrate, d, d))
pygame.draw.ellipse(display, grid[i][j].color, (r + d/2 + blocks/2 - d/2 + vibrate, c + blocks/2 - d/2, d, d))
elif grid[i][j].noAtoms == 3:
angle = 90
x = r + (d/2)*cos(radians(angle)) + blocks/2 - d/2
y = c + (d/2)*sin(radians(angle)) + blocks/2 - d/2
pygame.draw.ellipse(display, grid[i][j].color, (x - vibrate, y, d, d))
x = r + (d/2)*cos(radians(angle + 90)) + blocks/2 - d/2
y = c + (d/2)*sin(radians(angle + 90)) + 5
pygame.draw.ellipse(display, grid[i][j].color, (x + vibrate, y, d, d))
x = r + (d/2)*cos(radians(angle - 90)) + blocks/2 - d/2
y = c + (d/2)*sin(radians(angle - 90)) + 5
pygame.draw.ellipse(display, grid[i][j].color, (x - vibrate, y, d, d))
pygame.display.update()
# Increase the Atom when Clicked
def addAtom(i, j, color):
grid[i][j].noAtoms += 1
grid[i][j].color = color
if grid[i][j].noAtoms >= len(grid[i][j].neighbors):
overFlow(grid[i][j], color)
# Split the Atom when it Increases the "LIMIT"
def overFlow(cell, color):
showPresentGrid()
cell.noAtoms = 0
for m in range(len(cell.neighbors)):
cell.neighbors[m].noAtoms += 1
cell.neighbors[m].color = color
if cell.neighbors[m].noAtoms >= len(cell.neighbors[m].neighbors):
overFlow(cell.neighbors[m], color)
# Checking if Any Player has WON!
def isPlayerInGame():
global score
playerScore = []
for i in range(noPlayers):
playerScore.append(0)
for i in range(cols):
for j in range(rows):
for k in range(noPlayers):
if grid[i][j].color == players[k]:
playerScore[k] += grid[i][j].noAtoms
score = playerScore[:]
# GAME OVER
def gameOver(playerIndex):
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
close()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
close()
if event.key == pygame.K_r:
gameLoop()
text = font.render("Player %d Won!" % (playerIndex + 1), True, white)
text2 = font.render("Press \'r\' to Reset!", True, white)
display.blit(text, (width/3, height/3))
display.blit(text2, (width/3, height/2 ))
pygame.display.update()
clock.tick(60)
def checkWon():
num = 0
for i in range(noPlayers):
if score[i] == 0:
num += 1
if num == noPlayers - 1:
for i in range(noPlayers):
if score[i]:
return i
return 9999
# Main Loop
def gameLoop():
initializeGrid()
loop = True
turns = 0
currentPlayer = 0
vibrate = .5
while loop:
for event in pygame.event.get():
if event.type == pygame.QUIT:
close()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
close()
if event.type == pygame.MOUSEBUTTONDOWN:
x, y = pygame.mouse.get_pos()
i = x/blocks
j = y/blocks
if grid[i][j].color == players[currentPlayer] or grid[i][j].color == border:
turns += 1
addAtom(i, j, players[currentPlayer])
currentPlayer += 1
if currentPlayer >= noPlayers:
currentPlayer = 0
if turns >= noPlayers:
isPlayerInGame()
display.fill(background)
# Vibrate the Atoms in their Cells
vibrate *= -1
drawGrid(currentPlayer)
showPresentGrid(vibrate)
pygame.display.update()
res = checkWon()
if res < 9999:
gameOver(res)
clock.tick(20)
gameLoop()