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()