school

thing1's amazing school repo
Log | Files | Refs | Submodules | README

skel.py (7925B)


      1 #Skeleton Program code for the AQA A Level Paper 1 Summer 2025 examination
      2 #this code should be used in conjunction with the Preliminary Material
      3 #written by the AQA Programmer Team
      4 #developed in the Python 3.9 programming environment
      5 
      6 import re
      7 import random
      8 import math
      9 
     10 def Main():
     11     NumbersAllowed = []
     12     Targets = []
     13     MaxNumberOfTargets = 20
     14     MaxTarget = 0
     15     MaxNumber = 0
     16     TrainingGame = False
     17     Choice = input("Enter y to play the training game, anything else to play a random game: ").lower()
     18     print()
     19     if Choice == "y":
     20         MaxNumber = 1000
     21         MaxTarget = 1000
     22         TrainingGame = True
     23         Targets = [-1, -1, -1, -1, -1, 23, 9, 140, 82, 121, 34, 45, 68, 75, 34, 23, 119, 43, 23, 119]
     24     else:
     25         MaxNumber = 10
     26         MaxTarget = 50
     27         Targets = CreateTargets(MaxNumberOfTargets, MaxTarget)        
     28     NumbersAllowed = FillNumbers(NumbersAllowed, TrainingGame, MaxNumber)
     29     PlayGame(Targets, NumbersAllowed, TrainingGame, MaxTarget, MaxNumber)
     30     input()
     31 
     32 def PlayGame(Targets, NumbersAllowed, TrainingGame, MaxTarget, MaxNumber):
     33     Score = 0
     34     GameOver = False
     35     while not GameOver:
     36         DisplayState(Targets, NumbersAllowed, Score)
     37         UserInput = input("Enter an expression: ").replace(' ', '')
     38         if (UserInput == "QUIT"):
     39             break
     40         print()
     41         if CheckIfUserInputValid(UserInput):
     42             UserInputInRPN = ConvertToRPN(UserInput)
     43             if CheckNumbersUsedAreAllInNumbersAllowed(NumbersAllowed, UserInputInRPN, MaxNumber):
     44                 IsTarget, Score = CheckIfUserInputEvaluationIsATarget(Targets, UserInputInRPN, Score)
     45                 if IsTarget:
     46                     NumbersAllowed = RemoveNumbersUsed(UserInput, MaxNumber, NumbersAllowed)
     47                     NumbersAllowed = FillNumbers(NumbersAllowed, TrainingGame, MaxNumber)
     48         else:
     49             print("user input invalid!")
     50         Score -= 1
     51         if Score < 0:
     52             GameOver = True
     53         if Targets[0] != -1:
     54             GameOver = True
     55         else:
     56             Targets = UpdateTargets(Targets, TrainingGame, MaxTarget)        
     57     print("Game over!")
     58     DisplayScore(Score)
     59 
     60 def CheckIfUserInputEvaluationIsATarget(Targets, UserInputInRPN, Score):
     61     UserInputEvaluation = EvaluateRPN(UserInputInRPN)
     62     UserInputEvaluationIsATarget = False
     63     if UserInputEvaluation != -1:
     64         Score += 2
     65         for Count in range(0, len(Targets)):
     66             if Targets[Count] == UserInputEvaluation:
     67                 Targets[Count] = -1
     68                 UserInputEvaluationIsATarget = True        
     69     return UserInputEvaluationIsATarget, Score
     70 
     71 def RemoveNumbersUsed(UserInput, MaxNumber, NumbersAllowed):
     72     UserInputInRPN = ConvertToRPN(UserInput)
     73     for Item in UserInputInRPN:
     74         if CheckValidNumber(Item, MaxNumber):
     75             if int(Item) in NumbersAllowed:
     76                 NumbersAllowed.remove(int(Item))
     77     return NumbersAllowed
     78 
     79 def UpdateTargets(Targets, TrainingGame, MaxTarget):
     80     for Count in range (0, len(Targets) - 1):
     81         Targets[Count] = Targets[Count + 1]
     82     Targets.pop()
     83     if TrainingGame:
     84         Targets.append(Targets[-1])
     85     else:
     86         Targets.append(GetTarget(MaxTarget))
     87     return Targets
     88 
     89 def CheckNumbersUsedAreAllInNumbersAllowed(NumbersAllowed, UserInputInRPN, MaxNumber):
     90     Temp = []
     91     for Item in NumbersAllowed:
     92         Temp.append(Item)
     93     for Item in UserInputInRPN:
     94         if CheckValidNumber(Item, MaxNumber):
     95             if int(Item) in Temp:
     96                 Temp.remove(int(Item))
     97             else:
     98                 return False            
     99         else:
    100             if Item.isdigit() == True:
    101                 return False
    102     return True
    103 
    104 def CheckValidNumber(Item, MaxNumber):
    105     if re.search("^[0-9]+$", Item) is not None:
    106         ItemAsInteger = int(Item)
    107         if ItemAsInteger > 0 and ItemAsInteger <= MaxNumber:
    108             return True            
    109     return False
    110 
    111 def DisplayState(Targets, NumbersAllowed, Score):
    112     DisplayTargets(Targets)
    113     DisplayNumbersAllowed(NumbersAllowed)
    114     DisplayScore(Score)    
    115 
    116 def DisplayScore(Score):
    117     print("Current score: " + str(Score))
    118     print()
    119     print()
    120 
    121 def DisplayNumbersAllowed(NumbersAllowed):
    122     print("Numbers available: ", end = '')
    123     for N in NumbersAllowed:
    124         print(str(N) + "  ", end = '')
    125     print()
    126     print()
    127 
    128 def DisplayTargets(Targets):
    129     print("|", end = '')
    130     for T in Targets:
    131         if T == -1:
    132             print(" ", end = '')
    133         else:
    134             print(T, end = '')           
    135         print("|", end = '')
    136     print()
    137     print()
    138 
    139 def ConvertToRPN(UserInput):
    140     Position = 0
    141     Precedence = {"+": 2, "-": 2, "*": 4, "/": 4, "^": 6}
    142     Operators = []
    143     Operand, Position = GetNumberFromUserInput(UserInput, Position)
    144     UserInputInRPN = []
    145     UserInputInRPN.append(str(Operand))
    146     Operators.append(UserInput[Position - 1])
    147     while Position < len(UserInput):
    148         Operand, Position = GetNumberFromUserInput(UserInput, Position)
    149         UserInputInRPN.append(str(Operand))
    150         if Position < len(UserInput):
    151             CurrentOperator = UserInput[Position - 1]
    152             while len(Operators) > 0 and Precedence[Operators[-1]] > Precedence[CurrentOperator]:
    153                 UserInputInRPN.append(Operators[-1])
    154                 Operators.pop()                
    155             if len(Operators) > 0 and Precedence[Operators[-1]] == Precedence[CurrentOperator]:
    156                 UserInputInRPN.append(Operators[-1])
    157                 Operators.pop()    
    158             Operators.append(CurrentOperator)
    159         else:
    160             while len(Operators) > 0:
    161                 UserInputInRPN.append(Operators[-1])
    162                 Operators.pop()
    163     return UserInputInRPN
    164 
    165 def EvaluateRPN(UserInputInRPN):
    166     S = []
    167     while len(UserInputInRPN) > 0:
    168         while UserInputInRPN[0] not in ["+", "-", "*", "/", "^"]:
    169             S.append(UserInputInRPN[0])
    170             UserInputInRPN.pop(0)        
    171         Num2 = float(S[-1])
    172         S.pop()
    173         Num1 = float(S[-1])
    174         S.pop()
    175         Result = 0.0
    176         if UserInputInRPN[0] == "+":
    177             Result = Num1 + Num2
    178         elif UserInputInRPN[0] == "-":
    179             Result = Num1 - Num2
    180         elif UserInputInRPN[0] == "*":
    181             Result = Num1 * Num2
    182         elif UserInputInRPN[0] == "/":
    183             Result = Num1 / Num2
    184         elif UserInputInRPN[0] == "^":
    185             Result = Num1 ** Num2
    186         UserInputInRPN.pop(0)
    187         S.append(str(Result))       
    188     if float(S[0]) - math.floor(float(S[0])) == 0.0:
    189         return math.floor(float(S[0]))
    190     else:
    191         return -1
    192 
    193 def GetNumberFromUserInput(UserInput, Position):
    194     Number = ""
    195     MoreDigits = True
    196     while MoreDigits:    
    197         if not(re.search("[0-9]", str(UserInput[Position])) is None):
    198             Number += UserInput[Position]
    199         else:
    200             MoreDigits = False            
    201         Position += 1
    202         if Position == len(UserInput):
    203             MoreDigits = False
    204     if Number == "":
    205         return -1, Position
    206     else:
    207         return int(Number), Position    
    208 
    209 def CheckIfUserInputValid(UserInput):
    210     if re.search("^([0-9]+[\\+\\-\\*\\/\\^])+[0-9]+$", UserInput) is not None:
    211         return True
    212     else:
    213         return False
    214 
    215 def GetTarget(MaxTarget):
    216     return random.randint(1, MaxTarget)
    217 
    218 def GetNumber(MaxNumber):
    219     return random.randint(1, MaxNumber)   
    220 
    221 def CreateTargets(SizeOfTargets, MaxTarget):
    222     Targets = []
    223     for Count in range(1, 6):
    224         Targets.append(-1)
    225     for Count in range(1, SizeOfTargets - 4):
    226         Targets.append(GetTarget(MaxTarget))
    227     return Targets
    228 
    229 def FillNumbers(NumbersAllowed, TrainingGame, MaxNumber):
    230     if TrainingGame:
    231         return [2, 3, 2, 8, 512]
    232     else:
    233         while len(NumbersAllowed) < 5:
    234             NumbersAllowed.append(GetNumber(MaxNumber))      
    235         return NumbersAllowed
    236 
    237 if __name__ == "__main__":
    238     Main()