X Tutup
"""Dice Math, by Al Sweigart al@inventwithpython.com A flash card addition game where you sum the total on random dice rolls. View this code at https://nostarch.com/big-book-small-python-projects Tags: large, artistic, game, math""" import random, time # Set up the constants: DICE_WIDTH = 9 DICE_HEIGHT = 5 CANVAS_WIDTH = 79 CANVAS_HEIGHT = 24 - 3 # -3 for room to enter the sum at the bottom. # The duration is in seconds: QUIZ_DURATION = 30 # (!) Try changing this to 10 or 60. MIN_DICE = 2 # (!) Try changing this to 1 or 5. MAX_DICE = 6 # (!) Try changing this to 14. # (!) Try changing these to different numbers: REWARD = 4 # (!) Points awarded for correct answers. PENALTY = 1 # (!) Points removed for incorrect answers. # (!) Try setting PENALTY to a negative number to give points for # wrong answers! # The program hangs if all of the dice can't fit on the screen: assert MAX_DICE <= 14 D1 = (['+-------+', '| |', '| O |', '| |', '+-------+'], 1) D2a = (['+-------+', '| O |', '| |', '| O |', '+-------+'], 2) D2b = (['+-------+', '| O |', '| |', '| O |', '+-------+'], 2) D3a = (['+-------+', '| O |', '| O |', '| O |', '+-------+'], 3) D3b = (['+-------+', '| O |', '| O |', '| O |', '+-------+'], 3) D4 = (['+-------+', '| O O |', '| |', '| O O |', '+-------+'], 4) D5 = (['+-------+', '| O O |', '| O |', '| O O |', '+-------+'], 5) D6a = (['+-------+', '| O O |', '| O O |', '| O O |', '+-------+'], 6) D6b = (['+-------+', '| O O O |', '| |', '| O O O |', '+-------+'], 6) ALL_DICE = [D1, D2a, D2b, D3a, D3b, D4, D5, D6a, D6b] print('''Dice Math, by Al Sweigart al@inventwithpython.com Add up the sides of all the dice displayed on the screen. You have {} seconds to answer as many as possible. You get {} points for each correct answer and lose {} point for each incorrect answer. '''.format(QUIZ_DURATION, REWARD, PENALTY)) input('Press Enter to begin...') # Keep track of how many answers were correct and incorrect: correctAnswers = 0 incorrectAnswers = 0 startTime = time.time() while time.time() < startTime + QUIZ_DURATION: # Main game loop. # Come up with the dice to display: sumAnswer = 0 diceFaces = [] for i in range(random.randint(MIN_DICE, MAX_DICE)): die = random.choice(ALL_DICE) # die[0] contains the list of strings of the die face: diceFaces.append(die[0]) # die[1] contains the integer number of pips on the face: sumAnswer += die[1] # Contains (x, y) tuples of the top-left corner of each die. topLeftDiceCorners = [] # Figure out where dice should go: for i in range(len(diceFaces)): while True: # Find a random place on the canvas to put the die: left = random.randint(0, CANVAS_WIDTH - 1 - DICE_WIDTH) top = random.randint(0, CANVAS_HEIGHT - 1 - DICE_HEIGHT) # Get the x, y coordinates for all four corners: # left # v #top > +-------+ ^ # | O | | # | O | DICE_HEIGHT (5) # | O | | # +-------+ v # <-------> # DICE_WIDTH (9) topLeftX = left topLeftY = top topRightX = left + DICE_WIDTH topRightY = top bottomLeftX = left bottomLeftY = top + DICE_HEIGHT bottomRightX = left + DICE_WIDTH bottomRightY = top + DICE_HEIGHT # Check if this die overlaps with previous dice. overlaps = False for prevDieLeft, prevDieTop in topLeftDiceCorners: prevDieRight = prevDieLeft + DICE_WIDTH prevDieBottom = prevDieTop + DICE_HEIGHT # Check each corner of this die to see if it is inside # of the area the previous die: for cornerX, cornerY in ((topLeftX, topLeftY), (topRightX, topRightY), (bottomLeftX, bottomLeftY), (bottomRightX, bottomRightY)): if (prevDieLeft <= cornerX < prevDieRight and prevDieTop <= cornerY < prevDieBottom): overlaps = True if not overlaps: # It doesn't overlap, so we can put it here: topLeftDiceCorners.append((left, top)) break # Draw the dice on the canvas: # Keys are (x, y) tuples of ints, values the character at that # position on the canvas: canvas = {} # Loop over each die: for i, (dieLeft, dieTop) in enumerate(topLeftDiceCorners): # Loop over each character in the die's face: dieFace = diceFaces[i] for dx in range(DICE_WIDTH): for dy in range(DICE_HEIGHT): # Copy this character to the correct place on the canvas: canvasX = dieLeft + dx canvasY = dieTop + dy # Note that in dieFace, a list of strings, the x and y # are swapped: canvas[(canvasX, canvasY)] = dieFace[dy][dx] # Display the canvas on the screen: for cy in range(CANVAS_HEIGHT): for cx in range(CANVAS_WIDTH): print(canvas.get((cx, cy), ' '), end='') print() # Print a newline. # Let the player enter their answer: response = input('Enter the sum: ').strip() if response.isdecimal() and int(response) == sumAnswer: correctAnswers += 1 else: print('Incorrect, the answer is', sumAnswer) time.sleep(2) incorrectAnswers += 1 # Display the final score: score = (correctAnswers * REWARD) - (incorrectAnswers * PENALTY) print('Correct: ', correctAnswers) print('Incorrect:', incorrectAnswers) print('Score: ', score)
X Tutup