Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

24 game using Python [closed]

Tags:

python

There is a game called 24, which is a math-based game. If you are new to the game, please read this link http://en.wikipedia.org/wiki/24_Game

Anyways, this is a game where you get four numbers (in my cases, from 1 to 9) that are randomly selected, and try to combine them (using the four basic operations +, -, •, and ÷) to make the number 24. The rules are simple, you must use all four numbers and only those four numbers, and they can only be used once each. This game intrigued me enough to try and make a program to simulate this game.

My goal is to create a program like this using python. The basic algorithm is...

  • Generate 4 random numbers
  • check if they are equal to 24
  • display them to the user
  • see if the user's input also is equal to 24

I need the most help with step 2 and 4

I will use the random module to decide random integers

import random
num1 = random.randint ( 1, 9)
num2 = random.randint ( 1, 9)
num3 = random.randint ( 1, 9)
num4 = random.randint ( 1, 9)

So, please, if you can, help me create this game, and explain it to me too! thanks.

Also, this is my first time using stack overflow to ask a question, so please comment on how i can improve my asking skills :)

---EDIT--- Thanks for your help guys, but i finally figured it out. I did a bit of research and compiled together this (if any of you wish to try the code for yourselves):

>

 '''
 The 24 Game

 Given any four digits in the range 1 to 9, which may have repetitions,
 Using just the +, -, *, and / operators; and the possible use of
 brackets, (), show how to make an answer of 24.

 An answer of "!" will generate a new set of four digits (if your stuck).
 Otherwise you are repeatedly asked for an expression until it evaluates to 24

 Note: you cannot form multiple digit numbers from the supplied digits,
 so an answer of 12+12 when given 1, 2, 2, and 1 would not be allowed.

'''
from __future__ import division, print_function
import random, ast, re
import sys

while 1 == 1: 


if sys.version_info[0] < 3: input = raw_input

def choose4():
    'four random digits >0 as characters'
    return [str(random.randint(1,9)) for i in range(4)]

def welcome(digits):
    print (__doc__)
    print ("Your four digits: " + ' '.join(digits))

def check(answer, digits):
    allowed = set('() +-*/\t'+''.join(digits))
    ok = all(ch in allowed for ch in answer) and \
         all(digits.count(dig) == answer.count(dig) for dig in set(digits)) \
         and not re.search('\d\d', answer)
    if ok:
        try:
            ast.parse(answer)
        except:
            ok = False
    return ok

def main():    
    digits = choose4()
    welcome(digits)
    trial = 0
    answer = ''
    chk = ans = False
    while not (chk and ans == 24):
        trial +=1
        answer = input("Expression %i: " % trial)
        chk = check(answer, digits)
        if answer.lower() == 'q':
            break
        if answer == '!':
            digits = choose4()
            print ("New digits:", ' '.join(digits))
            continue
        if not chk:
            print ("The input '%s' was wonky!" % answer)
        else:
            ans = eval(answer)
            print (" = ", ans)
            if ans == 24:
                print ("Thats right!")   
main()

(python 3.3)

like image 466
sarora Avatar asked Jul 30 '14 04:07

sarora


1 Answers

I love 24! I remember playing it in elementary school.

First, let's consider the total number of permutations that would have to be evaluated for a given round of 24. In one round of play, four numbers are used and three operators are used.

We can arrange the numbers in 4! ways, which happens to equal 24 ways, haha.

We can arrange the three operators in 4p3 ways (ignoring the fact that addition and multiplication are commutative), which also happens to be 4!, which also happens to be 24 (OK this is starting to get creepy)

Edit: IIRC operations can be repeated, so there are actually 4**3, or 64 "op permutations". This brings us to 1560 permutations to check, which is still reasonable.

The total number of possible "24 equations" for a given selection of four random numbers is 24 * 24, which equals 576. Lucky for us, modern PCs can evaluate 576 arithmetic equations in just a few microseconds.

Before you prepare a 576 branch if-else tree, let's do this the elegant way.

As a warmup, first write a function that prints all permutations of the four random numbers, taking a list of the four random numbers as an argument. If you can't figure it out Google "permutations of a string Python"

Then write a function that prints all length 3 permutations of four operations (Edit: with repeats) that returns a list of 64 strings, i.e. ["aaa", "aas", ... , "amm", "amd", ... ] where 'a' stands for add, 's' for subtract, 'm' for multiply, and 'd' for divide.

Now you're ready to test all of the cases. Store the results of the first function in a list, Ns, store the results of the second function in a list, Ops, then

for ns in Ns:
    for ops in Ops:
        result = ns[0]
        result = op24(result, ops[0], ns[1])
        result = op24(result, ops[1], ns[2])
        result = op24(result, ops[3], ns[3])
        if result == 24:
            return True

    for ops in Ops:
        result1 = op24(ns[0], ops[0], ns[1])
        result2 = op24(ns[2], ops[1], ns[3])
        result = op24(result1, ops[2], result2)
        if result == 24:
            return True

# none of the permutations were equal to 24
return False

Edit: the difference between the inner loops above can be abstracted away if prefix expressions are generated and evaluated instead.

The op24 function is implemented like

def op24 (ns1, op, ns2):
    if op == 'a':
        return ns1 + ns2
    elif op == 's':
        return ns1 - ns2
    ...

Edit Use float() when evaluating, for clever players who will divide and multiply numbers not evenly divisible.

The "op24" function can be avoided by using Python's "op" module, and generating permutations of function references rather than "op strings", but as you seem like a beginner I'll leave that for another question ; ).

like image 193
OregonTrail Avatar answered Sep 23 '22 23:09

OregonTrail