A-level Computing/AQA/Problem Solving, Programming, Data Representation and Practical Exercise/Skeleton code/2014 Exam/Section D
Potential Questions
editAt the end of the game the player is asked to enter their name. Currently the player can just enter nothing by pressing Return. Modify the program to disallow empty inputs.
editVB.Net solution
Answer:
Modify the function GetPlayerName() as follows:
Function GetPlayerName() As String
Dim PlayerName As String
Console.WriteLine()
Do
Console.Write("Please enter your name: ")
PlayerName = Console.ReadLine
Loop Until PlayerName <> ""
Console.WriteLine()
Return PlayerName
End Function
an alternative solution
Function GetPlayerName() As String
Dim PlayerName As String
Do
Console.WriteLine()
Console.Write("Please enter your name: ")
PlayerName = Console.ReadLine
Console.WriteLine()
If PlayerName.Length = 0 Then
Console.WriteLine("INVALID - Please enter your name .")
End If
If PlayerName.Length > 15 Then
Console.WriteLine("INVALID - Please enter a name that is shorter than 15 characters.")
End If
Loop Until PlayerName.Length > 0 And PlayerName.Length <= 15
'I did this so that they have to enter a name and the length of the name is capped
Return PlayerName
End Function
Function GetPlayerName() As String
Dim PlayerName As String = ""
While PlayerName = "" Or PlayerName.Length > 15
Console.WriteLine()
Console.Write("Please enter your name (max 15 characters): ")
PlayerName = Console.ReadLine
Console.WriteLine()
End While
Return PlayerName
End Function
'mrclement@highcliffe
Python Solution
Answer:
# Paul Carpenter - PC Services
# Check valid name entry
# Must be at least 1 non-whitespace letter
# no numbers or punctuation or other symbols allowed
# add to top of file for lower and upper case translations
import string
# dont be tempted to use raw_input
# stops blamk entry and returns Title cased string
def GetPlayerName():
print()
while True:
Name = input( 'Please enter your name: ' )
# ensure not just whitespace
Name = Name.strip()
# Check not empty and only contains letters
if Name.isalpha():
break
print()
# Return name in title case
return Name.title()
# Test Section
PlayerName = GetPlayerName()
print( PlayerName )
def GetPlayerName():
print()
while True:
PlayerName = raw_input('Please enter your name: ')
if PlayerName != "":
break
print()
return PlayerName
Java solution
Answer:
String getPlayerName() {
String playerName = "";
console.println();
do {
playerName = console.readLine("Please enter your name: ");
console.println();
} while(playerName.length() == 0);
return playerName;
}
/* Dwarph */
Pascal solution
Answer:
Function GetPlayerName : String;
Var
PlayerName : String;
Begin
Writeln;
repeat
Write('Please enter your name: ');
Readln(PlayerName);
Writeln;
if PlayerName = '' then
writeln('That is an invalid input.');
until PlayerName <> '';
GetPlayerName := PlayerName;
End;
Save/Load Recent scores from a file
editVB.Net solution
Answer:
Sub UpdateRecentScores(ByRef RecentScores() As TRecentScore, ByVal Score As Integer)
Dim PlayerName, filename As String
Dim Count As Integer
Dim FoundSpace As Boolean
PlayerName = GetPlayerName()
'start of code to save scores to a file
filename = CurDir() & "scores.txt"
FileOpen(1, filename, OpenMode.Append)
WriteLine(1, PlayerName, Score)
FileClose(1)
'end of code to save scores to a file
FoundSpace = False
Count = 1
While Not FoundSpace And Count <= NoOfRecentScores
If RecentScores(Count).Name = "" Then
FoundSpace = True
Else
Count = Count + 1
End If
End While
If Not FoundSpace Then
For Count = 1 To NoOfRecentScores - 1
RecentScores(Count) = RecentScores(Count + 1)
Next
Count = NoOfRecentScores
End If
RecentScores(Count).Name = PlayerName
RecentScores(Count).Score = Score
End Sub
'Nathan Harries-Wood, Ecclesbourne School
Sub SaveScores(ByVal recentscores() As TRecentScore)
Dim writer As New System.IO.StreamWriter("U:\\FILEPATH\DOCUMENT.txt") ' creates file if none exists
For i = 1 To NoOfRecentScores
writer.WriteLine(recentscores(i).Name)
writer.WriteLine(recentscores(i).Score)
Next
writer.Close()
'Peter Chapman, Highdown School
End Sub
Function getscores(ByRef recentscores() As TRecentScore)
FileOpen(1, "file path", OpenMode.Input)
While Not EOF(1)
For i = 1 To NoOfRecentScores
recentscores(i).Name = (LineInput(1))
recentscores(i).Score = CInt(LineInput(1))
Next
End While
FileClose(1)
Return recentscores 'used to assign values to the in program variables rather than just displaying
End Function
'Dylan Patel
'Highdown
'Prof Brooks
Sub SaveRecentScores(ByVal RecentScores() As TRecentScore)
Using writer As StreamWriter = File.CreateText("Recentscores.txt")
For i As Integer = 1 To RecentScores.Count() - 1
writer.WriteLine(RecentScores(i).Name)
writer.WriteLine(RecentScores(i).Score)
Next
End Using
End Sub
Sub ReadSavedScores(ByRef RecentScores() As TRecentScore)
Using reader As StreamReader = File.OpenText("Recentscores.txt")
Dim line As String
For j As Integer = 1 To 3
line = reader.ReadLine()
RecentScores(j).Name = line
line = reader.ReadLine()
RecentScores(j).Score = line
Next
End Using
End Sub
'Alexander Miles
'Creates a *.txt file which is saved to and read from showing 3 most recent scores
'Put this in the (UpdateRecentScores) Sub, after the line (RecentScores(Count).Score = Name), but before the (End Sub)
RecentScores(Count).Score = Score
If Not My.Computer.FileSystem.FileExists(CurDir() + "Highscores.txt") Then 'Checks to see if "Highscores" file already exists
currentfilewriter = New StreamWriter(CurDir() + "Highscores.txt") 'Creates "Highscores" file if one doesn't exist
currentfilewriter.Close()
End If
SaveScoresToFile(RecentScores, Score, Count)'Reading the file
Sub DisplayScoresFromFile(ByRef recentscores() As TRecentScore, NoOfGamesPlayed As Integer)
Dim currentfilereader As StreamReader
Dim textstring As String
Dim Count, Count2, counter As Integer
Count = 0
If Not My.Computer.FileSystem.FileExists(CurDir() + "Highscores.txt") Then
Console.WriteLine("There are no recent scores to display.")
yno = Console.ReadLine()
Call Main()
End If
currentfilereader = New StreamReader(CurDir() + "Highscores.txt")
Do Until currentfilereader.EndOfStream
textstring = currentfilereader.ReadLine
Count = Count + 1
Loop
currentfilereader.Close()
currentfilereader = New StreamReader(CurDir() + "Highscores.txt")
If Count >= 7 Then
For Count2 = 1 To (Count - 6)
textstring = currentfilereader.ReadLine()
counter = counter + 1
Next
End If
Do Until currentfilereader.EndOfStream
textstring = currentfilereader.ReadLine
Console.WriteLine(Mid$(textstring, 4, 4) & " got a score of " & Mid$(textstring, 1, 3))
currentfilereader.ReadLine()
Loop
currentfilereader.Close()
End Sub
'Writing to the file
Sub SaveScoresToFile(ByRef RecentScores() As TRecentScore, ByVal Score As Integer, ByVal Count As Integer)
Dim filename, textstring As String
Dim Counter As Integer
Dim currentfilereader As StreamReader, currentfilewriter As StreamWriter
filename = (CurDir() + "Highscores.txt")
currentfilereader = New StreamReader(filename)
Do Until currentfilereader.EndOfStream 'Goes to end of "Highscores" file
textstring = currentfilereader.ReadLine
Counter = Count + 1
Loop
currentfilereader.Close()
currentfilewriter = New StreamWriter(filename, True)
textstring = (RecentScores(Count).Score)
If RecentScores(Count).Score < 10 Then
textstring = textstring + " "
Else
textstring = textstring + " "
End If 'Adds score data (name, score)
textstring = textstring + (RecentScores(Count).Name)
currentfilewriter.WriteLine(textstring)
currentfilewriter.WriteLine(" ")
currentfilewriter.Close()
Call Main()
End Sub
'Lord Sebastian Morrell
'==========================================================================================================================================================================================================
'/*A couple of simple functions "SaveScores" and "LoadScores" with one line modifications to "Main", "UpdateRecentScores" and "ResetRecentScores" using StreamReaders/Writers method.*/
'/*Don't forget to import the System.IO Library!*/
Sub SaveScores(ByVal RecentScores() As TRecentScore, ByVal FilePath As String)
Dim FileWriter As StreamWriter = New StreamWriter(FilePath & "/SavedScores.txt")
For index = 1 To NoOfRecentScores
FileWriter.WriteLine(RecentScores(index).Name)
FileWriter.WriteLine(RecentScores(index).Score)
Next
FileWriter.Close()
End Sub
Sub LoadScores(ByRef RecentScores() As TRecentScore, ByVal FilePath As String)
Dim FileReader As StreamReader
If File.Exists(FilePath & "/SavedScores.txt") = False Then '/*This if statement determines if the file already exists. This is only really used first time program is run*/
File.Create(FilePath & "/SavedScores.txt")
End If
FileReader = New StreamReader(FilePath & "/SavedScores.txt")
For index = 1 To NoOfRecentScores
RecentScores(index).Name = FileReader.ReadLine
RecentScores(index).Score = FileReader.ReadLine
Next
FileReader.Close()
End Sub
'Then add this:
SaveScores(RecentScores, CurDir()) '/* Simple function call to save the data */
'to bottom of "UpdateRecentScores" and "ResetRecentScores" and add this:
LoadScores(RecentScores, CurDir)
'above the Do Loop in "Main"
'/*Code Written by Kiran Joshi*/
'/*The Queen Katherine School, Kendal*/
Sub SaveRecentScores(ByVal RecentScores() As TRecentScore)
FileOpen(1, "RecentScores.txt", OpenMode.Binary)
For i = 1 To NoOfRecentScores
FilePut(1, RecentScores(i))
Next
FileClose(1)
End Sub
Sub LoadRecentScores(ByRef RecentSCores() As TRecentScore)
FileOpen(1, "RecentScores.txt", OpenMode.Binary)
While Not EOF(1)
For i = 1 To NoOfRecentScores
FileGet(1, RecentSCores(i))
Next
End While
FileClose(1)
End Sub
'Code written by George
'Very clean and quick saving and loading of scores
Python Solution
Answer:
# Better Solution
# Paul Carpenter PC Services
# do not pass GLOBALS as parameter to function
def SaveScores():
CurrentFile = open( "recentScores.txt", "w" )
for count in range( 1, NO_OF_RECENT_SCORES + 1 ):
Line = RecentScores[ count ].Name + "," + str( RecentScores[ count ].Score ) + "\n"
CurrentFile.write( Line )
CurrentFile.close( )
# do not pass GLOBALS as parameter to function
# Errors if no file, only loads as many lines in file or table size
# whichever comes first
def LoadScores():
try:
CurrentFile = open( "recentScores.txt", "r" )
except (OSError, IOError) as e:
print( 'No score table file found - Error: ', e.errno)
return
# Found a file to read
count = 1
# empty array class object
split = []
# Read lines from file until EOF or later break if RecentScores is smaller than lines in file
for line in CurrentFile :
# remove extra white space at ends
line = line.strip()
# split the line into two array items
split = line.split( ',' )
# Convert score to number
RecentScores[ count ].Score = int( split[ 1 ] )
# Change Name to title case
RecentScores[ count ].Name = split[ 0 ].title()
if count == NO_OF_RECENT_SCORES :
# break out as now filled score table at current size
break
# point to next table line
count += 1
# done close file
CurrentFile.close()
#Python Solution
def SaveScores(RecentScores):
currentFile = open("recentScores.txt","w")
count = 1
for count in range(1,NO_OF_RECENT_SCORES+1):
LineToAddToFile = RecentScores[count].Name + "," + str(RecentScores[count].Score) + "\n"
print(LineToAddToFile)
currentFile.write(LineToAddToFile)
currentFile.close()
'S Chell'
def getScores(RecentScores):
CurrentFile = open('recentScores.txt', 'r')
for count in range(1, NO_OF_RECENT_SCORES+1):
Values = [None,"",""]
LineFromFile = CurrentFile.readline()
count2 = 0
while LineFromFile[count2] != ",":
Values[1] += LineFromFile[count2]
count2 +=1
count2 +=1
while count2 < len(LineFromFile):
Values[2] += LineFromFile[count2]
count2 += 1
RecentScores[count].Name = Values[1]
RecentScores[count].Score = int(Values[2])
CurrentFile.close()
'This function only loads the scores, the DisplayRecentScores function will then have to be called.
'S Chell
Java solution
Answer:
public class Main {
AQAConsole2014 console = new AQAConsole2014();
final int NO_OF_RECENT_SCORES = 5;
Random random = new Random();
class TCard {
int suit;
int rank;
}
class TRecentScore {
String name;
int score;
}
public Main() {
char choice;
TCard[] deck = new TCard[53];
TRecentScore[] recentScores = new TRecentScore[NO_OF_RECENT_SCORES + 1];
for (int count = 1; count <= NO_OF_RECENT_SCORES; count++) {
recentScores[count] = new TRecentScore();
recentScores[count].name = "";
recentScores[count].score = 0;
}
do {
displayMenu();
choice = getMenuChoice();
switch (choice) {
case '1':
loadDeck(deck);
shuffleDeck(deck);
playGame(deck, recentScores);
break;
case '2':
loadDeck(deck);
playGame(deck, recentScores);
break;
case '3':
displayRecentScores(recentScores);
break;
case '4':
resetRecentScores(recentScores);
break;
case '5':
saveRecentScores(recentScores);
break;
case '6':
loadRecentScores();
break;
}
} while (choice != 'q');
}
void displayMenu() {
console.println();
console.println("MAIN MENU");
console.println();
console.println("1. Play game (with shuffle)");
console.println("2. Play game (without shuffle)");
console.println("3. Display recent scores");
console.println("4. Reset recent scores");
console.println("5. Save all recent scores");
console.println("6. Load previously saved recent scores");
console.println();
console.print("Select an option from the menu (or enter q to quit): ");
}
void saveRecentScores(TRecentScore[] recentScores){
AQAWriteTextFile2014 writefile = new AQAWriteTextFile2014("RecentScore.txt", false);
for (int count = 1; count <= NO_OF_RECENT_SCORES; count++) {
writefile.writeToTextFile(count +". " + recentScores[count].name +
" got a score of " + recentScores[count].score); }
writefile.closeFile();
console.println("Saved Files.");
}
void loadRecentScores(){
AQAReadTextFile2014 readfile = new AQAReadTextFile2014("RecentScore.txt");
for(int i = 0; i<NO_OF_RECENT_SCORES; i++){
String read = readfile.readLine();
console.println(read);
}
}
/* Dwarph */
/************************************************************************************************/
/*Another way to solve this problem is to load the text file into the array
* To do this we need to completely change the previous loadRecentScores method
* and we need to slightly edit the saveRecentScores method
* the answers are as follows:
*/
void saveRecentScores(TRecentScore[] recentScores){
rankScores(recentScores);
AQAWriteTextFile2014 writefile = new AQAWriteTextFile2014("RecentScore.txt", false);
for (int count = 1; count <= NO_OF_RECENT_SCORES; count++) {
writefile.writeToTextFile(recentScores[count].name +
"\n" + recentScores[count].score); }
writefile.closeFile();
console.println("Saved Files.");
}
void loadRecentScoresIntoArray(TRecentScore[] recentScores){
AQAReadTextFile2014 readfile = new AQAReadTextFile2014("RecentScore.txt");
for(int i = 1; i<=NO_OF_RECENT_SCORES; i++){
String read = readfile.readLine();
while (read != null) {
recentScores[i].name = read;
read = readfile.readLine();
recentScores[i].score = Integer.parseInt(read);
read = readfile.readLine();
i = i + 1;
}
readfile.closeFile();
}
}
/* Dwarph */
Pascal solution
Answer:
// Also be sure to uncomment {uses SysUtils;}
// Two new procedures to add anywhere
Procedure SaveScores;
Var
ScoresFile : Text;
Index : Integer;
Begin
AssignFile(ScoresFile, 'scores.txt');
Rewrite(ScoresFile);
For Index := 1 to NoOfRecentScores Do
Begin
Writeln(ScoresFile, RecentScores[index].Name);
Writeln(ScoresFile, RecentScores[index].Score);
End;
CloseFile(ScoresFile);
End;
Procedure LoadScores;
Var
ScoresFile : Text;
CurrentScore : String;
Index : Integer;
Begin
If FileExists('scores.txt') Then
Begin
AssignFile(ScoresFile, 'scores.txt');
Reset(ScoresFile);
For Index := 1 to NoOfRecentScores Do
Begin
Readln(ScoresFile, RecentScores[index].Name);
Readln(ScoresFile, CurrentScore);
RecentScores[index].Score := StrToInt(CurrentScore);
End;
CloseFile(ScoresFile);
End;
End;
// Add 'LoadScores;' just after 'Randomize;' on the main program.
// Add 'SaveScores;' just after 'Until Choice = 'q';' in the main program.
Ranked/Top/High Scores
editVB.Net solution
Answer:
' Enio F <http://eniof.com>
' Chelsea Independent College
' Reusing most of the UpdateRecentScores code (very efficient solution!)
Sub UpdateRecentScores(ByRef RecentScores() As TRecentScore, ByVal Score As Integer)
Dim PlayerName As String
Dim Count As Integer
Dim FoundSpace As Boolean
PlayerName = GetPlayerName()
FoundSpace = False
Count = 1
While Not FoundSpace And Count <= NoOfRecentScores
If RecentScores(Count).Name = "" Or Score > RecentScores(Count).Score Then
FoundSpace = True
Else
Count = Count + 1
End If
End While
If FoundSpace Then
For i = NoOfRecentScores To Count Step -1
RecentScores(i) = RecentScores(i - 1)
Next
RecentScores(Count).Name = PlayerName
RecentScores(Count).Score = Score
End If
End Sub
<syntaxhighlight lang="vbnet">
'Max Kramer <http://maxkramer.co>
'University College School, London.
Sub UpdateRecentScores(ByRef RecentScores() As TRecentScore, ByVal Score As Integer)
Dim PlayerName As String = GetPlayerName()
Dim Index = -1
Dim CIndex = 1
While Index = -1 And CIndex <= NoOfRecentScores
Dim TScore = RecentScores(CIndex)
If Score >= TScore.Score And Index = -1 Then
Index = CIndex
End If
CIndex += 1
End While
Dim NewR = New TRecentScore(PlayerName, Score)
If Index = NoOfRecentScores Then
RecentScores(NoOfRecentScores) = NewR
ElseIf Index = 1 Then
Dim Temp = RecentScores(Index)
RecentScores(Index) = NewR
Dim OtherTemp = RecentScores(Index + 1)
RecentScores(Index + 1) = Temp
RecentScores(Index + 2) = OtherTemp
ElseIf Index = 2 Then
Dim Temp = RecentScores(Index)
RecentScores(Index) = NewR
RecentScores(Index + 1) = Temp
End If
End Sub
'Jacob Moss, UCS School
'Penguins
Sub DisplayRecentScores(ByRef RecentScores() As TRecentScore)
Dim Count As Integer
Console.WriteLine()
Console.WriteLine("Highscores:")
Console.WriteLine()
Dim temp As TRecentScore
For co = 1 To NoOfRecentScores
For Count = 1 To NoOfRecentScores - 1
If (RecentScores(Count).Score < RecentScores(Count + 1).Score) Then
temp = RecentScores(Count)
RecentScores(Count) = RecentScores(Count + 1)
RecentScores(Count + 1) = temp
End If
Next
Next
For Count = 1 To NoOfRecentScores
If Not (String.IsNullOrWhiteSpace(RecentScores(Count).Name)) Then
Console.WriteLine(RecentScores(Count).Name & " got a score of " & RecentScores(Count).Score)
Else
Console.WriteLine("Empty score")
End If
Next
Console.WriteLine()
Console.WriteLine("Press the Enter key to return to the main menu")
Console.WriteLine()
Console.ReadLine()
End Sub
'this is an alternative solution which ranks the scores as it reads from the file
Sub GetHighscores(ByRef recentscores() As TRecentScore)
Dim temp(1000) As TRecentScore
For i = 1 To NoOfRecentScores
temp(i).Name = recentscores(i).Name
temp(i).Score = recentscores(i).Score
Next
Dim Count As Integer = 4 ' first three scores are from recentscores
If System.IO.File.Exists("U:\\Filepath\File.txt") Then
FileOpen(1, "U:\\Filepath\File.txt", OpenMode.Input)
While Not EOF(1)
temp(Count).Name = (LineInput(1))
temp(Count).Score = CInt(LineInput(1))
Count += 1
End While
FileClose(1)
For i = 1 To UBound(temp)
If temp(i).Score > recentscores(1).Score Then
recentscores(3) = recentscores(2)
recentscores(2) = recentscores(1)
recentscores(1) = temp(i)
ElseIf temp(i).Score > recentscores(2).Score Then
recentscores(3) = recentscores(2)
recentscores(2) = temp(i)
ElseIf temp(i).Score > recentscores(3).Score Then
recentscores(3) = temp(i)
End If
Next
End If
End Sub
' Peter Chapman, Highdown
' This works with my system of saving scores in the previous section
Sub DisplayHighScores()
Dim currentfilereader As StreamReader
Dim Count, Counter, Counter2 As Integer
Dim HighScores(500), HighScoreList(500) As String
Dim filename, textstring As String
Dim HighScoreNos(500) As Integer
filename = (CurDir() + "Highscores.txt")
If Not My.Computer.FileSystem.FileExists(filename) Then
Console.WriteLine("There are no high scores to display.")
yno = Console.ReadLine
Call Main()
End If
currentfilereader = New StreamReader(filename)
Count = 0
Do Until currentfilereader.EndOfStream
textstring = currentfilereader.ReadLine
HighScores(Count) = textstring
HighScoreNos(Count) = Mid$(textstring, 1, 3)
currentfilereader.ReadLine()
Count = Count + 1
Loop
currentfilereader.Close()
Array.Resize(HighScores, Count)
Array.Resize(HighScoreNos, Count)
Array.Resize(HighScoreList, Count)
Array.Sort(HighScores)
Array.Sort(HighScoreNos)
For Counter = 0 To Count - 1
For Counter2 = 0 To Count - 1
If HighScoreNos(Counter2) = (Mid$(HighScores(Counter), 1, 3)) Then
HighScoreList(Counter2) = HighScores(Counter)
End If
Next
Next
Console.WriteLine("TOP SCORE:")
Console.WriteLine((Mid$(HighScoreList(Count - 1), 4, 4)) & " got a score of " & (Mid$(HighScoreList(Count - 1), 1, 3)))
If Count >= 4 Then
Console.WriteLine()
Console.WriteLine("SECOND PLACE:")
Console.WriteLine((Mid$(HighScoreList(Count - 2), 4, 4)) & " got a score of " & (Mid$(HighScoreList(Count - 2), 1, 3)))
End If
If Count >= 6 Then
Console.WriteLine()
Console.WriteLine("THIRD PLACE:")
Console.WriteLine((Mid$(HighScoreList(Count - 3), 4, 4)) & " got a score of " & (Mid$(HighScoreList(Count - 3), 1, 3)))
End If
yno = Console.ReadLine
Call Main()
End Sub
'another alternative - this includes the load and save scores subs as well as a basic sort
Sub bubblesort(Byref Array)
Dim n As Integer = Array.length
Dim tempScore As TRecentScore
For co = 1 To n - 1
For Count = 1 To n - 2
If (Array(Count).Score < Array(Count + 1).Score) Then
tempScore = Array(Count)
Array(Count) = Array(Count + 1)
Array(Count + 1) = tempScore
End If
Next
Next
End Sub
Sub UpdateRecentScores(ByRef RecentScores() As TRecentScore, ByVal Score As Integer)
Dim PlayerName As String
Dim Count As Integer
Dim FoundSpace As Boolean
If (Score > RecentScores(NoOfRecentScores).Score) Then
PlayerName = GetPlayerName()
FoundSpace = False
Dim recentScoresCopy(NoOfRecentScores + 1) As TRecentScore
For Count = 1 To NoOfRecentScores
recentScoresCopy(Count) = RecentScores(Count)
Next
While Not FoundSpace And Count <= NoOfRecentScores + 1
If recentScoresCopy(Count).Name = "" Then
FoundSpace = True
Else
Count = Count + 1
End If
End While
If Not FoundSpace Then
For Count = 1 To NoOfRecentScores
recentScoresCopy(Count) = recentScoresCopy(Count + 1)
Next
Count = NoOfRecentScores + 1
End If
recentScoresCopy(Count).Name = PlayerName
recentScoresCopy(Count).Score = Score
bubblesort(recentScoresCopy)
For Count = 1 To NoOfRecentScores
RecentScores(Count) = recentScoresCopy(Count)
Next
SaveScores(RecentScores)
End If
End Sub
Sub SaveScores(ByVal RecentScores() As TRecentScore)
Dim objWriter As New System.IO.StreamWriter("scores.txt")
Dim Count As Integer
Dim record As TRecentScore
For Count = 1 To NoOfRecentScores
record = RecentScores(Count)
objWriter.WriteLine(record.Name)
objWriter.WriteLine(record.Score)
Next
objWriter.Close()
End Sub
Sub LoadScores(ByRef RecentScores() As TRecentScore)
Dim Count As Integer
FileOpen(1, "scores.txt", OpenMode.Input)
Count = 1
While Not EOF(1)
RecentScores(Count).Name = LineInput(1)
RecentScores(Count).Score = CInt(LineInput(1))
Count = Count + 1
End While
FileClose(1)
End Sub
'mrclement@highcliffe
Python Solution
Answer:
#Python Solution
def rankScores(RecentScores):
noMoreSwaps = False
while not noMoreSwaps:
noMoreSwaps = True
for count in range (1,NO_OF_RECENT_SCORES):
if (RecentScores[count].Score) < (RecentScores[count + 1].Score):
noMoreSwaps = False
tempScore = RecentScores[count].Score
tempName = RecentScores[count].Name
RecentScores[count].Score = RecentScores[count+1].Score
RecentScores[count].Name = RecentScores[count+1].Name
RecentScores[count+1].Score = tempScore
RecentScores[count+1].Name = tempName
DisplayRecentScores(RecentScores)
'S Chell
OR without moving the .Score and .Name separately
def rankScores(RecentScores):
noMoreSwaps = False #sets up local variable
while noMoreSwaps == False: #i.e. there are swaps still to do!
noMoreSwaps = True
for count in range (1,NO_OF_RECENT_SCORES):
if (RecentScores[count].Score) < (RecentScores[count + 1].Score): #compares to find highest score
noMoreSwaps = False
tempScore = RecentScores[count] #next 3 lines swap over the two scores
RecentScores[count] = RecentScores[count+1]
RecentScores[count+1] = tempScore
DisplayRecentScores(RecentScores) #print new leaderboard
'MrsCMH
# Alternative method change ho UpdateScores works by only saving high scores
# Paul Carpenter - PC Services
# Similar ArrayList methods can be used in VB.net and Java
# Note other methods change the GLOBAL score table so after next game the first score gone is the highest
# Change UpdateRecentScores to the following
# Remove parameter of RecentScores as Globals should NOT be passed as
# parameters with SAME name in function definition
#
# As previous code gets Player name
# Scans table finds first time score is higher
# Inserts new score (pushing rest down)
# Removes last entry as list is one longer than required to return to normal size
# Exit for loop and exit function
# This works with array of empty values up to full
# Goes to end of for loop if not a high score and does not update
def UpdateRecentScores( NewScore ):
PlayerName = GetPlayerName()
# Scan our high score table
for Count in range( 1, NO_OF_RECENT_SCORES + 1 ):
if RecentScores[ Count ].Score < NewScore:
# Insert new element in array ( a class object)
RecentScores.insert( Count, TRecentScore( PlayerName, NewScore ) )
# remove last element as no an extra element
del RecentScores[ -1 ]
# exit for loop and function
break
Java solution
Answer:
//add "rankScores(recentScores);"
//to the top of the method displayRecentScores
void rankScores(TRecentScore[] recentScores){
for (int count = 1; count<NO_OF_RECENT_SCORES; count++){
if (recentScores[count].score < recentScores[count + 1].score){
int tempScore = recentScores[count].score;
String tempName = recentScores[count].name;
recentScores[count].score = recentScores[count+1].score;
recentScores[count].name = recentScores[count+1].name;
recentScores[count+1].score = tempScore;
recentScores[count+1].name = tempName;
}
}
}
/*Dwarph */
Pascal solution
Answer:
// James Tarpy Longbenton Community College Newcastle upon Tyne
Procedure UpdateRecentScores(Var RecentScores : TRecentScores; Score : Integer);
Var
PlayerName : String;
Count : Integer;
loopagain : boolean;
storescore : TRecentScores;
count2 : integer;
Begin
PlayerName := GetPlayerName;
Count := 1;
loopagain :=true;
storescore := RecentScores; //store the recent scores in a temporary array
while (loopagain) and (count<=noofrecentscores) do
//keep looping until you run out of scores and loop again is true
begin
if score > recentscores[count].score then //this checks each score in the array
begin //and if it beats it then it overwrites it with the new high score
recentscores[count].score:= score;
recentscores[count].name:= playername;
for count2:= count to noofrecentscores
Do recentscores[count2+1]:=storescore[count2]; //and move all the scores down one place
loopagain:=false;
end; //set loopagain false so no more looping
count:=count+1;
end;
End;
Add a new suit to the deck
editVB.Net solution
Answer:
Function GetSuit(ByVal SuitNo As Integer) As String Dim Suit As String = "" Select Case SuitNo Case 1 : Suit = "Clubs" Case 2 : Suit = "Diamonds" Case 3 : Suit = "Hearts" Case 4 : Suit = "Spades" Case 5 : Suit = "Swords" End Select Return Suit End Function
// Also in every instance of 52 or 51 add 13 to increase the deck size to accommodate another suit and add this to the text file: 5 1 5 2 5 3 5 4 5 5 5 6 5 7 5 8 5 9 5 10 5 11 5 12 5 13
Python Solution
Answer:
def GetSuit(SuitNo):
Suit = ''
if SuitNo == 1:
Suit = 'Clubs'
elif SuitNo == 2:
Suit = 'Diamonds'
elif SuitNo == 3:
Suit = 'Hearts'
elif SuitNo == 4:
Suit = 'Spades'
elif SuitNo == 5:
Suit = 'Swords'
return Suit
Java solution
Answer:
String getSuit(int suitNo) {
String suit = "";
switch (suitNo) {
case 1:
suit = "Clubs";
break;
case 2:
suit = "Diamonds";
break;
case 3:
suit = "Hearts";
break;
case 4:
suit = "Spades";
break;
case 5:
/* add an extra suit to the deck.txt (5 1 5 2 5 3 ect)
* every instance in the code where 51 or 52 appears +13
* to accommodate the new suit. */
suit= "Swords";
break;
}
return suit;
}
/* Dwarph */
Pascal solution
Answer:
//Solution
//James Tarpy Longbenton Community College Newcastle upon Tyne
Function GetSuit(SuitNo : Integer) : String;
Var
Suit : String;
Begin
Suit := '';
Case SuitNo Of
1 : Suit := 'Clubs';
2 : Suit := 'Diamonds';
3 : Suit := 'Hearts';
4 : Suit := 'Spades';
5 : Suit := 'Swords'; // new suit
End;
GetSuit := Suit;
End;
//You also need to change every hardcoded incidence of 52/51 in the whole program to
// take account of the fact there are now 65 cards in the pack
// and change the data.txt file by adding 13 extra Sword cards as so
// 515253545556575859510511512513
Change the objective of the game to higher or lower rather than just higher or not
editVB.Net solution
Answer:
Sub Main()
Dim Choice As Char
Dim Deck(65) As TCard
Dim RecentScores(NoOfRecentScores) As TRecentScore
Randomize()
Do
DisplayMenu()
Choice = GetMenuChoice()
Select Case Choice
Case "1"
LoadDeck(Deck)
ShuffleDeck(Deck)
PlayGame(Deck, RecentScores)
Case "2"
LoadDeck(Deck)
PlayGame(Deck, RecentScores)
Case "3"
LoadDeck(Deck)
ShuffleDeck(Deck)
PlayHighOrLow(Deck, RecentScores)
Case "4"
DisplayRecentScores(RecentScores)
Case "5"
ResetRecentScores(RecentScores)
End Select
Loop Until Choice = "q"
End Sub
Sub DisplayMenu()
Console.WriteLine()
Console.WriteLine("MAIN MENU")
Console.WriteLine()
Console.WriteLine("1. Play game (with shuffle)")
Console.WriteLine("2. Play game (without shuffle)")
Console.WriteLine("3. Play game(higher or lower)")
Console.WriteLine("4. Display recent scores")
Console.WriteLine("5. Reset recent scores")
Console.WriteLine()
Console.Write("Select an option from the menu (or enter q to quit): ")
End Sub
Function IsNextCardLower(ByVal LastCard As TCard, ByVal NextCard As TCard) As Boolean
Dim Lower As Boolean = False
If NextCard.Rank < LastCard.Rank Then
Lower = True
End If
Return Lower
End Function
Function GetHighOrLowFromUser() As Char
Dim Choice As Char
Console.Write("Do you think the next card will be higher or lower (enter h or l)? ")
Choice = Console.ReadLine.tolower
Return Choice
End Function
Sub PlayHighOrLow(ByVal Deck() As TCard, ByRef RecentScores() As TRecentScore)
Dim NoOfCardsTurnedOver As Integer
Dim GameOver, Higher, lower As Boolean
Dim NextCard, lastcard As TCard
Dim Choice As Char
GameOver = False
GetCard(LastCard, Deck, 0)
DisplayCard(LastCard)
NoOfCardsTurnedOver = 1
While NoOfCardsTurnedOver < 65 And Not GameOver
GetCard(NextCard, Deck, NoOfCardsTurnedOver)
Do
Choice = GetHighOrLowFromUser()
Loop Until Choice = "h" Or Choice = "l"
DisplayCard(NextCard)
NoOfCardsTurnedOver = NoOfCardsTurnedOver + 1
Higher = IsNextCardHigher(LastCard, NextCard)
Lower = IsNextCardLower(LastCard, NextCard)
If Higher And Choice = "h" Or Lower And Choice = "l" Then
DisplayCorrectGuessMessage(NoOfCardsTurnedOver - 1)
LastCard = NextCard
Else
GameOver = True
End If
End While
If GameOver Then
DisplayEndOfGameMessage(NoOfCardsTurnedOver - 2)
UpdateRecentScores(RecentScores, NoOfCardsTurnedOver - 2)
Else
DisplayEndOfGameMessage(64)
UpdateRecentScores(RecentScores, 64)
End If
End Sub
'no you didn't dylan
'oh yes you did
'highdown
Python Solution
Answer:
'This is an amendment to the PlayGame function rather than a new function
Although a new function called IsNextCardLower() is required. See below
below that is the amended PlayGame() function'
def IsNextCardLower(LastCard, NextCard):
Lower = False
if NextCard.Rank < LastCard.Rank:
Lower = True
return Lower
def PlayGame(Deck, RecentScores):
LastCard = TCard()
NextCard = TCard()
GameOver = False
GetCard(LastCard, Deck, 0)
DisplayCard(LastCard)
NoOfCardsTurnedOver = 1
while (NoOfCardsTurnedOver < 52) and (not GameOver):
GetCard(NextCard, Deck, NoOfCardsTurnedOver)
Choice = ''
Choice = GetChoiceFromUser() #change to accept l or h
while (Choice != 'h') and (Choice != 'l'): #change to test for l or h
Choice = GetChoiceFromUser()
print(Choice)
if (Choice =="q")or (Choice =="Q"):
sys.exit()
DisplayCard(NextCard)
NoOfCardsTurnedOver = NoOfCardsTurnedOver + 1
Higher = IsNextCardHigher(LastCard, NextCard)
Lower = IsNextCardLower(LastCard,NextCard) # new function
if (Higher and Choice == 'h') or (Lower and Choice =='l'):#new if statement
DisplayCorrectGuessMessage(NoOfCardsTurnedOver - 1)
LastCard.Rank = NextCard.Rank
LastCard.Suit = NextCard.Suit
else:
GameOver = True
if GameOver:
DisplayEndOfGameMessage(NoOfCardsTurnedOver - 2)
UpdateRecentScores(RecentScores, NoOfCardsTurnedOver - 2)
else:
DisplayEndOfGameMessage(51)
UpdateRecentScores(RecentScores, 51)
#Python Solution
Java solution
Answer:
/* For this solution I also made ace count as both higher or lower
* Another option could be to add a message if it is an ace, you may
* want to try this
* Dwarph
*/
//this method checks to see if it is an ace
boolean isNextCardAce (TCard lastCard, TCard nextCard){
boolean aceCheck;
aceCheck=false;
if(nextCard.rank ==2){
aceCheck=true;
}
return aceCheck;
}
void updateRecentScores(TRecentScore[] recentScores, int score) {
String playerName;
int count;
boolean foundSpace;
playerName = getPlayerName();
foundSpace = false;
count = 1;
while (!foundSpace && count <= NO_OF_RECENT_SCORES) {
if (recentScores[count].name.equals("")) {
foundSpace = true;
} else {
count = count + 1;
}
}
if (!foundSpace) {
for (count = 1; count <= NO_OF_RECENT_SCORES - 1; count++) {
recentScores[count].name = recentScores[count + 1].name;
recentScores[count].score = recentScores[count + 1].score;
}
count = NO_OF_RECENT_SCORES;
}
recentScores[count].name = playerName;
recentScores[count].score = score;
}
void numberOfGames(){
noOfGames++;
console.println("You have played " +noOfGames + " games this session.");
}
void averageScore(TRecentScore[] recentScores){
int averageSum=0, averageDiv=0, sessionGame = 0;
for(int i= 1; i<=NO_OF_RECENT_SCORES; i++){
if(recentScores[i].score!=0){
averageSum= averageSum + recentScores[i].score;
sessionGame++;
}
}
if(sessionGame<NO_OF_RECENT_SCORES){
averageDiv = averageSum/sessionGame;
console.println("Your Average Score for this session is: " + averageDiv);
}
else{
averageDiv = averageSum/NO_OF_RECENT_SCORES;
console.println("Your Average Score for this session is: " + averageDiv);
}
}
void playGame(TCard[] deck, TRecentScore[] recentScores) {
int noOfCardsTurnedOver;
boolean gameOver;
int counter = 2;
TCard nextCard;
TCard lastCard;
nextCard = new TCard();
lastCard = new TCard();
boolean higher;
boolean aceCheck;
char choice;
gameOver = false;
getCard(lastCard, deck, 0);
displayCard(lastCard);
noOfCardsTurnedOver = 1;
while (noOfCardsTurnedOver < 52+13 && !gameOver && counter>=1) {
getCard(nextCard, deck, noOfCardsTurnedOver);
do {
choice = getChoiceFromUser();
} while (!(choice == 'h' || choice == 'l' || choice == 'q')); //changed to h or l
displayCard(nextCard);
noOfCardsTurnedOver = noOfCardsTurnedOver + 1;
higher = isNextCardHigher(lastCard, nextCard);
aceCheck = isNextCardAce (lastCard,nextCard);
//changed to h/2 and added !aceCheck as if it is an Ace youd just get a free point
if (!aceCheck &&!higher && choice =='h' || !aceCheck&&higher && choice=='l') {
counter--;
console.println("Lives Left: " + counter);
}
//changed to h/2 and added aceCheck as if it is an Ace you get a free point
if (aceCheck ||higher && choice =='h' ||!higher && choice=='l' ){
displayCorrectGuessMessage(noOfCardsTurnedOver - 1);
lastCard.rank = nextCard.rank;
lastCard.suit = nextCard.suit;
}
if(counter<=0 || choice=='q') {
gameOver = true;
}
}
if (gameOver) {
displayEndOfGameMessage(noOfCardsTurnedOver - 2);
updateRecentScores(recentScores, noOfCardsTurnedOver - 2);
numberOfGames();
averageScore(recentScores);
} else {
displayEndOfGameMessage(51+13);
updateRecentScores(recentScores, 51+13);
}
}
Pascal solution
Answer:
//Solution
Use the suit of the card to determine if the same value card is higher or not - suits are ranked 1 to 4 as they are in Bridge - Clubs, Diamonds, Hearts, Spades
editVB.Net solution
Answer:
Enter this as IsNextCardHigher
Function IsNextCardHigher(ByVal LastCard As TCard, ByVal NextCard As TCard) As Boolean
Dim Higher As Boolean = false
If NextCard.Rank = LastCard.Rank Then
If NextCard.Suit > LastCard.Suit Then
Higher = True
End If
Return Higher
End If
If NextCard.Rank > LastCard.Rank Then
Higher = True
End If
Return Higher
End Function
'Mr Patel 'Highdown
'More efficient version which uses ELSE
Function IsNextCardHigher(ByVal LastCard As TCard, ByVal NextCard As TCard) As Boolean
Dim Higher As Boolean = false
If NextCard.Rank = LastCard.Rank Then
If NextCard.Suit > LastCard.Suit Then
Higher = True
End if
Else
If NextCard.Rank > LastCard.Rank Then
Higher = True
End If
End If
Return Higher
End Function
Python Solution
Answer:
- Python Solution
Please note this solution amends the existing PlayGame function rather than creates a complete new function. It does need a need function called IsNextCardLower(LastCard, NextCard)
def IsNextCardLower(LastCard, NextCard):
Lower = False
if NextCard.Rank < LastCard.Rank:
Lower = True
return Lower
'Amended PlayGame Function'
def PlayGame(Deck, RecentScores):
LastCard = TCard()
NextCard = TCard()
GameOver = False
GetCard(LastCard, Deck, 0)
DisplayCard(LastCard)
NoOfCardsTurnedOver = 1
while (NoOfCardsTurnedOver < 52) and (not GameOver):
GetCard(NextCard, Deck, NoOfCardsTurnedOver)
Choice = ''
Choice = GetChoiceFromUser() #change to accept l or h
while (Choice != 'h') and (Choice != 'l'): #change to test for l or h
Choice = GetChoiceFromUser()
print(Choice)
if (Choice =="q")or (Choice =="Q"):
sys.exit()
DisplayCard(NextCard)
NoOfCardsTurnedOver = NoOfCardsTurnedOver + 1
Higher = IsNextCardHigher(LastCard, NextCard)
Lower = IsNextCardLower(LastCard,NextCard) # new function
if (Higher and Choice == 'h') or (Lower and Choice =='l'):#new if statement
DisplayCorrectGuessMessage(NoOfCardsTurnedOver - 1)
LastCard.Rank = NextCard.Rank
LastCard.Suit = NextCard.Suit
else:
GameOver = True
if GameOver:
DisplayEndOfGameMessage(NoOfCardsTurnedOver - 2)
UpdateRecentScores(RecentScores, NoOfCardsTurnedOver - 2)
else:
DisplayEndOfGameMessage(51)
UpdateRecentScores(RecentScores, 51)
Java solution
Answer:
boolean isNextCardHigher(TCard lastCard, TCard nextCard){
boolean higher;
higher = false;
if (nextCard.rank > lastCard.rank){
higher=true;
}
if(nextCard.rank==lastCard.rank){
if (nextCard.suit < lastCard.suit){
higher = false;
}
else if(nextCard.suit > lastCard.suit){
higher=true;
}
}
return higher;
}
/* Dwarph */
Pascal solution
Answer:
Function IsNextCardHigher(LastCard, NextCard : TCard) : Boolean;
Var
Higher : Boolean;
Begin
Higher := False;
If NextCard.Rank > LastCard.Rank
Then Higher := True;
If NextCard.Rank = LastCard.Rank then
begin
If NextCard.Suit > LastCard.Suit then
Higher :=true;
end;
IsNextCardHigher := Higher;
End;
'S Chell
Getting the Users choice to choose if the next card will be higher will not accept capital letters. Modify the code to allow this.
editVB.Net solution
Answer:
Function GetChoiceFromUser() As Char
Dim Choice As Char
Console.Write("Do you think the next card will be higher than the last card (enter y or n)? ")
Choice = Console.ReadLine.ToLower 'Adding the .ToLower at the end of the Console.Readline statement converts the content of 'GetChoiceFromUser' to the lower case
Return Choice
End Function
'Highdown
Function GetChoiceFromUser() As Char
Dim Choice As Char
Console.Write("Do you think the next card will be higher than the last card (enter y or n)? ")
Choice = LCase(Console.ReadLine)
Return Choice
End Function
'Osy
Python Solution
Answer:
def GetChoiceFromUser():
Choice = input('Do you think the next card will be higher than the last card (enter y or n)? ').lower() #Adding .lower() here will force capitals to lowercase.
return Choice
Java solution
Answer:
char getChoiceFromUser() {
char choice;
choice = console.readChar("Do you think the next card will be "
+ "higher than the last card (enter y or n)? ");
if(choice=='Y'){
choice='y';
}
if (choice=='N'){
choice='n';
}
if (choice!= 'y' && choice!= 'n' && choice!= 'Y' && choice!= 'N'){
console.println("Invalid move! please choose Y or N.");
}
return choice;
}
/* You can also use the method .toLowerCase- see below:*/
/*******************************************************/
char getChoiceFromUser() {
char choice;
choice = console.readChar("Do you think the next card will be "
+ "higher or lower than the last card (enter h or l)? ");
String choiceString = String.valueOf(choice);
choiceString=choiceString.toLowerCase();
choice = choiceString.charAt(0);
/*TODO change to tolowercase
*Need to change choice to a String to do so.
*
*/
return choice;
}
/*Dwarph */
/* Another alternative is to use the Character.toLowerCase() method instead of converting to and from strings */
char getChoiceFromUser() {
char choice;
choice = console.readChar("Do you think the next card will be "
+ "higher or lower than the last card (enter h or l)? ");
choice = Character.toLowerCase(choice); // Convert to lower case
return choice;
}
/* Dan Foad */
Pascal solution
Answer:
//Made by AK
//Make sure to use StrUtils
Function GetChoiceFromUser : Char;
Var
Choice : Char;
Begin
Write('Do you think the next card will be higher than the last card (enter y or n)? ');
Readln(Choice);
GetChoiceFromUser := LowerCase(Choice);
End;
Currently there is no way to quit during the game. Allow the user to quit during the game.
editVB.Net solution
Answer:
Sub PlayGame(ByVal Deck() As TCard, ByRef RecentScores() As TRecentScore)
Dim NoOfCardsTurnedOver As Integer
Dim GameOver As Boolean
Dim NextCard As TCard
Dim LastCard As TCard
Dim Higher As Boolean
Dim Choice As Char
GameOver = False
GetCard(LastCard, Deck, 0)
DisplayCard(LastCard)
NoOfCardsTurnedOver = 1
While NoOfCardsTurnedOver < 52 And Not GameOver
GetCard(NextCard, Deck, NoOfCardsTurnedOver)
Do
Choice = GetChoiceFromUser()
If Choice = "q" Then 'if the input is q it will go back to the sub main
Call Main()
End If
Loop Until Choice = "y" Or Choice = "n"
DisplayCard(NextCard)
NoOfCardsTurnedOver = NoOfCardsTurnedOver + 1
Higher = IsNextCardHigher(LastCard, NextCard)
If Higher And Choice = "y" Or Not Higher And Choice = "n" Then
DisplayCorrectGuessMessage(NoOfCardsTurnedOver - 1)
LastCard = NextCard
Else
GameOver = True
End If
End While
If GameOver Then
DisplayEndOfGameMessage(NoOfCardsTurnedOver - 2)
UpdateRecentScores(RecentScores, NoOfCardsTurnedOver - 2)
Else
DisplayEndOfGameMessage(51)
UpdateRecentScores(RecentScores, 51)
End If
End Sub
End Module
'Dan B, Ecclesbourne
Python Solution
Answer:
#Python Solution
#Added a if choice ==q then call sys.exit()
#You need to remember to import sys at the beginning
def PlayGame(Deck, RecentScores):
LastCard = TCard()
NextCard = TCard()
GameOver = False
GetCard(LastCard, Deck, 0)
DisplayCard(LastCard)
NoOfCardsTurnedOver = 1
while (NoOfCardsTurnedOver < 52) and (not GameOver):
GetCard(NextCard, Deck, NoOfCardsTurnedOver)
Choice = ''
while (Choice != 'y') and (Choice != 'n'):
Choice = GetChoiceFromUser()
if (Choice == "q"):
sys.exit()
DisplayCard(NextCard)
NoOfCardsTurnedOver = NoOfCardsTurnedOver + 1
Higher = IsNextCardHigher(LastCard, NextCard)
if (Higher and Choice == 'y') or (not Higher and Choice == 'n'):
DisplayCorrectGuessMessage(NoOfCardsTurnedOver - 1)
LastCard.Rank = NextCard.Rank
LastCard.Suit = NextCard.Suit
else:
GameOver = True
if GameOver:
DisplayEndOfGameMessage(NoOfCardsTurnedOver - 2)
UpdateRecentScores(RecentScores, NoOfCardsTurnedOver - 2)
else:
DisplayEndOfGameMessage(51)
UpdateRecentScores(RecentScores, 51)
Java solution
Answer:
void playGame(TCard[] deck, TRecentScore[] recentScores) {
int noOfCardsTurnedOver;
boolean gameOver;
TCard nextCard;
TCard lastCard;
nextCard = new TCard();
lastCard = new TCard();
boolean higher;
char choice;
gameOver = false;
getCard(lastCard, deck, 0);
displayCard(lastCard);
noOfCardsTurnedOver = 1;
while (noOfCardsTurnedOver < 52+13 && !gameOver && counter>=1) {
getCard(nextCard, deck, noOfCardsTurnedOver);
do {
choice = getChoiceFromUser();
} while (!(choice == 'y' || choice == 'n' || choice == 'q'));
displayCard(nextCard);
noOfCardsTurnedOver = noOfCardsTurnedOver + 1;
higher = isNextCardHigher(lastCard, nextCard);
if (higher && choice =='y' || !higher && choice=='n') {
displayCorrectGuessMessage(noOfCardsTurnedOver - 1);
lastCard.rank = nextCard.rank;
lastCard.suit = nextCard.suit;
}
if(choice=='q') {
gameOver = true;
}
}
if (gameOver) {
displayEndOfGameMessage(noOfCardsTurnedOver - 2);
updateRecentScores(recentScores, noOfCardsTurnedOver - 2);
} else {
displayEndOfGameMessage(51+13);
updateRecentScores(recentScores, 51+13);
}
}
/* Dwarph */
Pascal solution
Answer:
(Whenever the user is asked to enter an input, you can check if the user enters 'q', if so use the 'halt' command to end the program)
if input = 'q' then
GameOver := True;
Limit the user's "username" to X characters
editVB.Net Solution
Answer:
Function GetPlayerName() As String
Dim PlayerName As String
Console.WriteLine()
Console.Write("Please enter your name: ")
PlayerName = Console.ReadLine()
'previous code checked if the length was BIGGER or equal to 10. not SMALLER. it has now been changed
If PlayerName.Length <= 10 And PlayerName.Length <> 0 Then
Console.WriteLine()
Else
Console.WriteLine("The name you have entered is too long or too short, please enter a name UNDER 10 CHARACTERS.")
GetPlayerName()
End If
Return PlayerName
End Function
an alternative solution
Function GetPlayerName() As String
Dim PlayerName As String
Do
Console.WriteLine()
Console.Write("Please enter your name: ")
PlayerName = Console.ReadLine
Console.WriteLine()
If PlayerName.Length = 0 Then
Console.WriteLine("INVALID - Please enter your name.")
End If
If PlayerName.Length > 15 Then
Console.WriteLine("INVALID - Please enter a name that is shorter than 15.")
End If
Loop Until PlayerName.Length > 0 And PlayerName.Length <= 15
'i did this so that they have to enter a name and the length of the name is capped
Return PlayerName
End Function
'why write such complex code? the following alternative solution works. if you want to tell the user the constraints of the name string just put it in early in the do loop
Function GetPlayerName() As String
Dim PlayerName As String
Do
Console.WriteLine()
'enter any commands relating to the type of string to use as the name here
Console.Write("Please enter your name: ")
PlayerName = Console.ReadLine
PlayerName = UCase(PlayerName)
Console.WriteLine()
Loop Until PlayerName <> "" And PlayerName.Length > 4
Return PlayerName
End Function
'EFORD
NOTE: This piece of code has also disallowed an input of 0 characters for the 'username'. Therefore the username must be between 1 and 10 characters long. Jack.Wall
Python Solution
Answer:
def GetPlayerName(MaximumLengthName):
while True:
PlayerName = input('Please enter your name: ')
if PlayerName != '':
if len(PlayerName) <= MaximumLengthName:
break
return PlayerName
Note: This also has the fix for Question 1
Java solution
Answer:
String getPlayerName() {
String playerName = "";
int limit = 10; // Change limit as appropriate
console.println();
playerName = console.readLine("Please enter your name: ");
console.println();
while (playerName.length() == 0 || playerName.length() > limit){
playerName = console.readLine("Please enter your name: ");
console.println();
}
return playerName;
}
/* Dwarph & Dan Foad */
Pascal solution
Answer:
//Made by AK
Function GetPlayerName : String;
Var
PlayerName : String;
Begin
Writeln;
While (Length(PlayerName) < 3) or (Length (PlayerName) > 14) do
begin
Write('Please enter your name: ');
Readln(PlayerName);
if (Length(PlayerName) < 3) or (Length(PlayerName) > 14) then
begin
writeln('Please enter a name of at least 3 characters and less than a total of 15');
end;
writeln;
end;
GetPlayerName := PlayerName;
End;
Using the previously shown cards show a percentage of the next card being higher.
editSecond Python solution is a less compute intensive solution than most, and works all way from 1st to last card. Easy to port to other languages
'Note: none of these solutions take into account the fact that the total cards in each rank decreases
VB.Net solution
Answer:
Function Calc(ByVal LastCard As TCard) As Integer
Dim mul As Integer = LastCard.Rank
prob = (100 - (mul * 4 / 52 * 100))
Return prob 'Prob is a global variable
End Function
prob = Calc(LastCard)
Console.WriteLine("The probability of the Next card being higher is " & prob & "%") 'Place in the while loop in the PlayGame sub
'
'Danté G - Loxford
'Edit: Fastest and the most efficient and mathematical way of doing this~
'
Function probabilityHigher(lastCard As TCard) As Integer
Dim prob As Integer
If lastCard.Rank = 1 Then
prob = 48 / 51 * 100
ElseIf lastCard.Rank = 2 Then
prob = 44 / 51 * 100
ElseIf lastCard.Rank = 3 Then
prob = 40 / 51 * 100
ElseIf lastCard.Rank = 4 Then
prob = 36 / 51 * 100
ElseIf lastCard.Rank = 5 Then
prob = 32 / 51 * 100
ElseIf lastCard.Rank = 6 Then
prob = 28 / 51 * 100
ElseIf lastCard.Rank = 7 Then
prob = 24 / 51 * 100
ElseIf lastCard.Rank = 8 Then
prob = 20 / 51 * 100
ElseIf lastCard.Rank = 9 Then
prob = 16 / 51 * 100
ElseIf lastCard.Rank = 10 Then
prob = 12 / 51 * 100
ElseIf lastCard.Rank = 11 Then
prob = 8 / 51 * 100
ElseIf lastCard.Rank = 12 Then
prob = 4 / 51 * 100
ElseIf lastCard.Rank = 13 Then
prob = 0
End If
Return prob
End Function
'charlieb
'
'Edit: This will only work correctly for the first card drawn
'
Function probabilityHigher(ByVal lastCard As TCard) As Integer
Dim HigherProb As Integer
Dim TotalCards As Integer = 51
Dim RankProb(12) As Integer
For i = 0 To 12
Select Case i
Case "0"
RankProb(0) = 48
Case "1"
RankProb(1) = 44
Case "2"
RankProb(2) = 40
Case "3"
RankProb(3) = 36
Case "4"
RankProb(4) = 32
Case "5"
RankProb(5) = 28
Case "6"
RankProb(6) = 24
Case "7"
RankProb(7) = 20
Case "8"
RankProb(8) = 16
Case "9"
RankProb(9) = 12
Case "10"
RankProb(10) = 8
Case "11"
RankProb(11) = 4
Case "12"
RankProb(12) = 0
End Select
Next
If lastCard.Rank = 1 Then
HigherProb = RankProb(0) / TotalCards * 100
If RankProb(0) <> 0 Then
RankProb(0) = RankProb(0) - 1
End If
TotalCards = TotalCards - 1
ElseIf lastCard.Rank = 2 Then
HigherProb = RankProb(1) / TotalCards * 100
If RankProb(1) <> 0 Then
RankProb(1) = RankProb(1) - 1
End If
TotalCards = TotalCards - 1
ElseIf lastCard.Rank = 3 Then
HigherProb = RankProb(2) / TotalCards * 100
If RankProb(2) <> 0 Then
RankProb(2) = RankProb(2) - 1
End If
TotalCards = TotalCards - 1
ElseIf lastCard.Rank = 4 Then
HigherProb = RankProb(3) / TotalCards * 100
If RankProb(3) <> 0 Then
RankProb(3) = RankProb(3) - 1
End If
TotalCards = TotalCards - 1
ElseIf lastCard.Rank = 5 Then
HigherProb = RankProb(4) / TotalCards * 100
If RankProb(4) <> 0 Then
RankProb(4) = RankProb(4) - 1
End If
TotalCards = TotalCards - 1
ElseIf lastCard.Rank = 6 Then
HigherProb = RankProb(5) / TotalCards * 100
If RankProb(5) <> 0 Then
RankProb(5) = RankProb(5) - 1
End If
TotalCards = TotalCards - 1
ElseIf lastCard.Rank = 7 Then
HigherProb = RankProb(6) / TotalCards * 100
If RankProb(6) <> 0 Then
RankProb(6) = RankProb(6) - 1
End If
TotalCards = TotalCards - 1
ElseIf lastCard.Rank = 8 Then
HigherProb = RankProb(7) / TotalCards * 100
If RankProb(7) <> 0 Then
RankProb(7) = RankProb(7) - 1
End If
TotalCards = TotalCards - 1
ElseIf lastCard.Rank = 9 Then
HigherProb = RankProb(8) / TotalCards * 100
If RankProb(8) <> 0 Then
RankProb(8) = RankProb(8) - 1
End If
TotalCards = TotalCards - 1
ElseIf lastCard.Rank = 10 Then
HigherProb = RankProb(9) / TotalCards * 100
If RankProb(9) <> 0 Then
RankProb(9) = RankProb(9) - 1
End If
TotalCards = TotalCards - 1
ElseIf lastCard.Rank = 11 Then
HigherProb = RankProb(10) / TotalCards * 100
If RankProb(10) <> 0 Then
RankProb(10) = RankProb(10) - 1
End If
TotalCards = TotalCards - 1
ElseIf lastCard.Rank = 12 Then
HigherProb = RankProb(11) / TotalCards * 100
If RankProb(11) <> 0 Then
RankProb(11) = RankProb(11) - 1
End If
TotalCards = TotalCards - 1
ElseIf lastCard.Rank = 13 Then
HigherProb = RankProb(12)
TotalCards = TotalCards - 1
End If
Return HigherProb
End Function
'
'Not very efficient, lots of lines of code but it should work for every card
'Ben.B
Python Solution
Answer:
def SetPercentAge(CurrentDeck, LastCard):
HigherCard = 0
for i in range(1, len(CurrentDeck)):
if IsNextCardHigher(LastCard, CurrentDeck[i]):
HigherCard = HigherCard + 1
percentage = round((HigherCard / len(CurrentDeck))*100)
print(" the next card being higher is" , percentage, " %")
return
then have to add to the main fuction
def PlayGame(Deck, RecentScores):
LastCard = TCard()
NextCard = TCard()
GameOver = False
GetCard(LastCard, Deck, 0)
DisplayCard(LastCard)
NoOfCardsTurnedOver = 1
while (NoOfCardsTurnedOver < 52) and (not GameOver):
GetCard(NextCard, Deck, NoOfCardsTurnedOver)
SetPercentAge(Deck, LastCard)
Choice = ''
while (Choice != 'h') and (Choice != 'l') and (Choice != "q"):## do higher or lower
Choice = GetChoiceFromUser()
if Choice != "q":
Less Compute intensive solution every GetCard does ONE subtract, and MAX of 12 numbers to SUM to get percentage
# Paul Carpenter - PC Services
# Display Percentage chance of next card being Higher (or Higher or equal depending on setting)
#
# Algorithm
# 1/ Start of each game reset array of CardsRank[ 1 to 13 ] to 4
# as each array entry is the count of that rank still to be dealt so = 4 of each rank at start
# 2/ As each card is dealt subtract one from CardsRank[ index ] where index matches rank of card
# 3/ After displaying card
# Sum all CardsRank[ index ] where index > rank (or index >= rank)
# calculate cards left
# Calculate percentage chance = sum / cards left
# Display percentage before prompt
# Add global
# Count of each rank still to be dealt (note first 0 index not used)
CardsRank = [ 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 ]
# add line to end of GetCard
def GetCard( ThisCard, Deck, NoOfCardsTurnedOver ):
# Make an actual value copy of card into the object reference
ThisCard.Suit = Deck[ 1 ].Suit
ThisCard.Rank = Deck[ 1 ].Rank
for Count in range( 1, 52 - NoOfCardsTurnedOver ):
Deck[ Count ] = Deck[ Count + 1 ]
Deck[ 52 - NoOfCardsTurnedOver ].Suit = 0
Deck[ 52 - NoOfCardsTurnedOver ].Rank = 0
# One less of this rank to be dealt
CardsRank[ ThisCard.Rank ] -= 1
# Add new function
def DisplayChance( Card, CardsTurned ) :
sum = 0
# sum card rank totals above for higher only (start Card.Rank + 1 )
# or current rank and above for higher or same (start Card.Rank )
for loop in range( Card.Rank + 1, 14 ) :
sum += CardsRank[ loop ]
# Calculate percentage if there are some cards above
if sum > 0 :
sum /= ( 52.00 - CardsTurned )
sum *= 100
print( 'Chance of Higher card is {:6.2f}%'.format( sum + 0.005 ) )
# Modify PlayGame (only start of function showwn)
def PlayGame( Deck ):
LastCard = TCard()
NextCard = TCard()
# Reset Rank totals to be dealt to 4 (max possible)
for loop in range( 1, 14 ) :
CardsRank[ loop ] = 4
GameOver = False
GetCard( LastCard, Deck, 0 )
DisplayCard( LastCard )
NoOfCardsTurnedOver = 1
while (NoOfCardsTurnedOver < 52) and (not GameOver) :
# Display current percentage chance of being higher
DisplayChance( LastCard, NoOfCardsTurnedOver )
GetCard( NextCard, Deck, NoOfCardsTurnedOver )
Java solution
Answer:
//Solution
Pascal solution
Answer:
//Solution
Procedure ResetDealtCards(var DealtCards:TDealtCards);
//set all elements to 0 before a game is played
var
rank: integer;
begin
for rank:=1 to 13 do
DealtCards[Rank]:=0;
end;
Procedure UpdateDealtCards( LastCard:Tcard;
var DealtCards: TdealtCards);
//add 1 to the count of the rank belonging to the last card.
//called after every card is dealt
var
rank: integer;
begin
rank:=LastCard.Rank;
DealtCards[rank]:=DealtCards[rank]+1;
end;
Function GetProbabilityofHigherCard(LastCard:TCard;
DealtCards: TDealtCards;
NoOfCardsDealt: integer) : real;
//calculate the probablity of the next card being Higher than the LastCard
//uses the array of DealtCards and the NoOfCardsDealt
var
lastRank: integer;
index: integer;
countOfHigher: integer;
cardsLeft: integer;
prob: real;
begin
lastRank:=LastCard.Rank;
countOfHigher:=0;
if lastRank<13 then
for index:= lastRank+1 to 13 do
countOfHigher:= countOfHigher + DealtCards[index];
//at this point countOfHigher contains the number of cards DEALT which are higher
countOfHigher:=4*(13-lastRank) - countOfHigher;
//at this point countOfHigher contains the number of cards NOT dealt which are higher
cardsLeft := 52-NoOfCardsDealt;
prob:= countOfHigher / cardsLeft;
GetProbabilityofHigherCard:=prob;
end;
Allow the user a certain number of card swaps if they don't like the card dealt to them (Based on Bruce's "Play Your Cards Right" for those of a certain age!)
editVB.Net solution
Answer:
Sub PlayGame(ByVal Deck() As TCard, ByRef RecentScores() As TRecentScore)
Dim NoOfCardsTurnedOver As Integer
Dim GameOver As Boolean
Dim NextCard As TCard
Dim LastCard As TCard
Dim Higher As Boolean
Dim Choice As Char
Dim noOfSwaps As Integer = 3
GameOver = False
GetCard(LastCard, Deck, 0)
DisplayCard(LastCard)
NoOfCardsTurnedOver = 1
While NoOfCardsTurnedOver < 52 And Not GameOver
GetCard(NextCard, Deck, NoOfCardsTurnedOver)
Do
Choice = GetChoiceFromUser()
Loop Until Choice = "y" Or Choice = "n" Or Choice = "q" Or Choice = "s"
If Choice = "q" Then
GameOver = True
ElseIf Choice = "s" Then
noOfSwaps = noOfSwaps - 1
If noOfSwaps >= 0 Then
DisplayCard(NextCard)
LastCard = NextCard
Console.WriteLine(noOfSwaps & " swaps remaining")
Else
Console.WriteLine("No swaps remaining")
End If
Else
DisplayCard(NextCard)
NoOfCardsTurnedOver = NoOfCardsTurnedOver + 1
Higher = IsNextCardHigher(LastCard, NextCard)
If Higher And Choice = "y" Or Not Higher And Choice = "n" Then
DisplayCorrectGuessMessage(NoOfCardsTurnedOver - 1)
LastCard = NextCard
Else
GameOver = True
End If
End If
End While
If GameOver Then
DisplayEndOfGameMessage(NoOfCardsTurnedOver - 2)
UpdateRecentScores(RecentScores, NoOfCardsTurnedOver - 2)
Else
DisplayEndOfGameMessage(51)
UpdateRecentScores(RecentScores, 51)
End If
End Sub
'Charley Baker
Sub PlayGame(ByVal Deck() As TCard, ByRef RecentScores() As TRecentScore)
Dim NoOfCardsTurnedOver As Integer
Dim GameOver As Boolean
Dim NextCard As TCard
Dim LastCard As TCard
Dim Higher As Boolean
Dim Choice As Char
Dim replacementSuit As Integer
Dim replacementRank As Integer
swapcount = 0
GameOver = False
gamesplayed = gamesplayed + 1
GetCard(LastCard, Deck, 0)
DisplayCard(LastCard)
NoOfCardsTurnedOver = 1
While NoOfCardsTurnedOver < 52 And Not GameOver
GetCard(NextCard, Deck, NoOfCardsTurnedOver)
If (swapcount < swaplimit) Then
Do
Choice = GetChoiceFromUser()
Loop Until Choice = "h" Or Choice = "l" Or Choice = "q" Or Choice = "s"
Else
Do
Choice = GetChoiceFromUser()
Loop Until Choice = "h" Or Choice = "l" Or Choice = "q"
End If
If Choice = "s" Then
swapcount = swapcount + 1
replacementRank = CInt(Math.Ceiling(Rnd() * 13))
replacementSuit = CInt(Math.Ceiling(Rnd() * 4))
NextCard.Rank = replacementRank
NextCard.Suit = replacementSuit
DisplayCard(NextCard)
LastCard = NextCard
Else
DisplayCard(NextCard)
NoOfCardsTurnedOver = NoOfCardsTurnedOver + 1
Higher = IsNextCardHigher(LastCard, NextCard)
If Higher And Choice = "h" Or Not Higher And Choice = "l" Then
DisplayCorrectGuessMessage(NoOfCardsTurnedOver - 1)
LastCard = NextCard
Else
GameOver = True
End If
If Choice = "q" Then
GameOver = True
End If
End If
End While
If GameOver Then
DisplayEndOfGameMessage(NoOfCardsTurnedOver - 2)
UpdateRecentScores(RecentScores, NoOfCardsTurnedOver - 2)
Else
DisplayEndOfGameMessage(51)
UpdateRecentScores(RecentScores, 51)
End If
End Sub
Function GetChoiceFromUser() As Char
Dim Choice As Char
Console.WriteLine("Do you think the next card will be higher or lower than the last card ? ")
Console.WriteLine("Enter h for higher l for lower")
Console.WriteLine("Enter q to quit")
If (swapcount < swaplimit) Then
Console.WriteLine("Enter s to swap card for a random one")
Console.WriteLine("You have " & swaplimit - swapcount & " swaps remaining.")
End If
Choice = Console.ReadLine.ToLower
Return Choice
End Function
Module CardPredict
Dim swapcount As Integer = 0
Const swaplimit As Integer = 3
...........
'mrclement@highcliffe
Python Solution
Answer:
#Python Solution
Java solution
Answer:
char getChoiceFromUser(int cardSwapsLeft)
{
char choice;
if (cardSwapsLeft > 0)
{
choice = console.readChar("Do you think the next card will be higher than the last card, or would you like to swap cards (enter y, n or s)? [Card Swaps Left: " + cardSwapsLeft + "]");
}
else
{
choice = console.readChar("Do you think the next card will be higher than the last card (enter y or n)? ");
}
return choice;
}
void playGame(TCard[] deck, TRecentScore[] recentScores)
{
int noOfCardsTurnedOver, cardSwapsLeft = 3; // Sets the number of card swaps allowed
boolean gameOver;
TCard nextCard;
TCard lastCard;
nextCard = new TCard();
lastCard = new TCard();
boolean higher;
char choice = ' '; // Initialised variable to allow its use in a future if statement
gameOver = false;
getCard(lastCard, deck, 0);
displayCard(lastCard);
noOfCardsTurnedOver = 1;
while (noOfCardsTurnedOver < 52 && !gameOver)
{
if (choice != 's') getCard(nextCard, deck, noOfCardsTurnedOver); // New if statement to stop the deck being moved up 1 if the user previously swapped cards
do
{
choice = getChoiceFromUser(cardSwapsLeft);
if (choice == 's' && cardSwapsLeft == 0) console.println("You have no swaps left!"); // Notifies user if they try to input 's' but have no swaps left
}
while (!(choice == 'y' || choice == 'n' || (choice == 's' && cardSwapsLeft > 0))); // New condition: valid if user enters 's' and has swaps left
if (choice == 's') // New if statement handling the new swapping feature
{
int swapIndex = 1 + random.nextInt(52 - noOfCardsTurnedOver - 2); // Picks the index of the card that last card is swapped with
TCard temp = new TCard();
temp.rank = lastCard.rank; // Swaps cards using a temporary TCard
temp.suit = lastCard.suit;
lastCard.rank = deck[swapIndex].rank;
lastCard.suit = deck[swapIndex].suit;
deck[swapIndex].rank = temp.rank;
deck[swapIndex].suit = temp.suit;
cardSwapsLeft--; // Decrements number of swaps left
console.println("\n\nYour new card is the " + getRank(lastCard.rank) + " of " + getSuit(lastCard.suit) + "\n"); // Notifies the user of their new card
}
else // Stops the turn carrying on as normal if user just swapped cards
{
displayCard(nextCard);
noOfCardsTurnedOver = noOfCardsTurnedOver + 1;
higher = isNextCardHigher(lastCard, nextCard);
if (higher && choice == 'y' || !higher && choice == 'n')
{
displayCorrectGuessMessage(noOfCardsTurnedOver - 1);
lastCard.rank = nextCard.rank;
lastCard.suit = nextCard.suit;
}
else
{
gameOver = true;
}
}
}
if (gameOver)
{
displayEndOfGameMessage(noOfCardsTurnedOver - 2);
updateRecentScores(recentScores, noOfCardsTurnedOver - 2);
}
else
{
displayEndOfGameMessage(51);
updateRecentScores(recentScores, 51);
}
}
/* Tom */
Pascal solution
Answer:
//Solution
Record the number of games played and an average score
editVB.Net solution
Answer:
'Working on average score, but I have 2 codes for number of games
'This code displays the games played in a session at the "GAME OVER" screen
Sub DisplayEndOfGameMessage(ByVal Score As Integer) 'This can just replace the Sub of the same name
NoOfGamesPlayed = NoOfGamesPlayed + 1 ' Remember to Dim this variable at the top
Console.WriteLine()
Console.WriteLine("GAME OVER!")
Console.WriteLine("Your score was " & Score)
If Score = 51 Then
Console.WriteLine("WOW! You completed a perfect game.")
End If
If NoOfGamesPlayed > 1 then
Console.WriteLine("You have played " & NoOfGamesPlayed & " games this session.")
Else
Console.WriteLine("You have played " & NoOfGamesPlayed & " game this session.")
End If
Console.WriteLine()
End Sub
'This code writes & reads from a file, displaying total number of games
Sub DisplayEndOfGameMessage(ByVal Score As Integer)
Dim currentfilereader As StreamReader, currentfilewriter As StreamWriter
If My.Computer.FileSystem.FileExists(CurDir() + "Gamesplayed.txt") Then
currentfilereader = New StreamReader(CurDir() + "Gamesplayed.txt")
NoOfGamesPlayed = currentfilereader.ReadLine()
currentfilereader.Close()
End If
NoOfGamesPlayed = NoOfGamesPlayed + 1
currentfilewriter = New StreamWriter(CurDir() + "Gamesplayed.txt")
currentfilewriter.WriteLine(NoOfGamesPlayed)
currentfilewriter.Close()
Console.WriteLine()
Console.WriteLine("GAME OVER!")
Console.WriteLine("Your score was " & Score)
If Score = 51 Then
Console.WriteLine("WOW! You completed a perfect game.")
End If
If NoOfGamesPlayed > 1 Then
Console.WriteLine("You have played " & NoOfGamesPlayed & " games in total.")
Else
Console.WriteLine("You have played " & NoOfGamesPlayed & " game in total.")
End If
Console.WriteLine()
End Sub
'You're welcome
'SLAW the LAD
'Ecclesbourne School
Sub DisplayEndOfGameMessage(ByVal Score As Integer)
Console.WriteLine()
Console.WriteLine("GAME OVER!")
Console.WriteLine("Your score was " & Score)
If Score = 51 Then
Console.WriteLine("WOW! You completed a perfect game.")
End If
Console.WriteLine()
Console.WriteLine(gamesplayed & " games played this session")
If averagescore > 0 Then
averagescore = ((averagescore * (gamesplayed - 1)) + Score) / gamesplayed
Console.WriteLine("Average Score: " & averagescore)
Else
averagescore = Score / gamesplayed
Console.WriteLine("Average Score: " & averagescore)
End If
End Sub
Module CardPredict
Dim gamesplayed As Integer = 0
Dim averagescore As Integer = 0
.....
Sub PlayGame(ByVal Deck() As TCard, ByRef RecentScores() As TRecentScore)
gamesplayed = gamesplayed + 1
.....
'mrclement@highcliffe
Python Solution
Answer:
#Python Solution
# Modify 2014 Python Skeleton code
# Paul Carpenter - PC Services
# Calculate and display games statistics
# Create extra menu item for display of statistics
# Add running totals to play game
# Improve some code for easier totalling
# Add two GLOBALS
Games = 0
TotalScore = 0
# Change Menu
def DisplayMenu():
print()
print( 'MAIN MENU' )
print()
print( '1. Play game (with shuffle)' )
print( '2. Play game (without shuffle)')
print( '3. Display recent scores' )
print( '4. Reset recent scores' )
print( '9. Display Session Game statistics' )
print()
print( 'Select an option from the menu (or enter q to quit): ', end='' )
# Change PlayGame
def PlayGame(Deck, RecentScores):
# Extra Game played
Games += 1
NewScore = 0
LastCard = TCard()
NextCard = TCard()
GameOver = False
GetCard(LastCard, Deck, 0)
DisplayCard(LastCard)
NoOfCardsTurnedOver = 1
while (NoOfCardsTurnedOver < 52) and (not GameOver):
GetCard(NextCard, Deck, NoOfCardsTurnedOver)
Choice = ''
while (Choice != 'y') and (Choice != 'n'):
Choice = GetChoiceFromUser()
DisplayCard(NextCard)
NoOfCardsTurnedOver = NoOfCardsTurnedOver + 1
Higher = IsNextCardHigher(LastCard, NextCard)
if (Higher and Choice == 'y') or (not Higher and Choice == 'n'):
DisplayCorrectGuessMessage(NoOfCardsTurnedOver - 1)
LastCard.Rank = NextCard.Rank
LastCard.Suit = NextCard.Suit
else:
GameOver = True
# Get new score
if GameOver:
NewScore = NoOfCardsTurnedOver - 2
else:
NewScore = 51
# Do updates and display using this new score
DisplayEndOfGameMessage( NewScore )
UpdateRecentScores(RecentScores, NewScore )
TotalScore += NewScore
# Add function DisplayStats
def DisplayStats( )
print( 'Game Statistics: ' )
print( ' Games Played =', Games )
print( ' Average Score =', int( ( TotalScore / Games ) + 0.5 ) )
print()
print( 'Press the Enter key to return to the main menu' )
input()
print()
# Change Main Menu loop
if __name__ == '__main__':
for Count in range(1, 53):
Deck.append( TCard() )
for Count in range(1, NO_OF_RECENT_SCORES + 1):
RecentScores.append( TRecentScore() )
Choice = ''
while Choice != 'q':
DisplayMenu()
Choice = GetMenuChoice()
if Choice == '1':
LoadDeck( Deck )
ShuffleDeck( Deck )
PlayGame( Deck, RecentScores )
elif Choice == '2':
LoadDeck( Deck )
PlayGame( Deck, RecentScores )
elif Choice == '3':
DisplayRecentScores( RecentScores )
elif Choice == '4':
ResetRecentScores( RecentScores )
elif Choice == '9':
DisplayStats( )
Java solution
Answer:
void numberOfGames(){
noOfGames++;
console.println("You have played " +noOfGames + " games this session.");
}
void averageScore(TRecentScore[] recentScores){
int averageSum=0, averageDiv=0, sessionGame = 0;
for(int i= 1; i<=NO_OF_RECENT_SCORES; i++){
if(recentScores[i].score !=0){ //Shouldn't this check against .name instead of .score? Otherwise we would fail to include games which scored 0
averageSum= averageSum + recentScores[i].score;
sessionGame++;
}
}
if(sessionGame<NO_OF_RECENT_SCORES){
if(averageSum==0){
console.println("Your Average Score for this session is: 0");
}
else{
averageDiv = averageSum/sessionGame;
console.println("Your Average Score for this session is: " + averageDiv);
}
}
else{
averageDiv = averageSum/NO_OF_RECENT_SCORES;
console.println("Your Average Score for this session is: " + averageDiv);
}
}
/* I added the methods numberOfGames and averageScore to the gameOver condition in the playGame method
Remember to put it AFTER the score is updated!!!!
Dwarph */
Pascal solution
Answer:
//Solution
Give a player 2 lives. If they get it wrong they lose a life
editVB.Net solution
Answer:
''Taken from Sub PlayGame(ByVal Deck() As TCard, ByRef RecentScores() As TRecentScore)
Dim lives As Integer = 2
If Higher And Choice = "y" Or Not Higher And Choice = "n" Then
DisplayCorrectGuessMessage(NoOfCardsTurnedOver - 1)
LastCard = NextCard
Else
LastCard = NextCard
lives = lives - 1 ''wrong guess removes a life
System.Console.ForegroundColor = ConsoleColor.Red ''Using color so it stands out
Console.WriteLine("You have lost a life, you have " & lives & " remaining")
System.Console.ForegroundColor = ConsoleColor.Gray
If lives = 0 Then ''If no lives remain, gameover
GameOver = True
End If
End If
'Osy
Python Solution
Answer:
#added a variable lives
lives=2
LastCard = TCard()
NextCard = TCard()
GameOver = False
GetCard(LastCard, Deck, 0)
DisplayCard(LastCard)
NoOfCardsTurnedOver = 1
while (NoOfCardsTurnedOver < 52) and (not GameOver):
GetCard(NextCard, Deck, NoOfCardsTurnedOver)
Choice = ''
while (Choice != 'y') and (Choice != 'n'):
Choice = GetChoiceFromUser()
DisplayCard(NextCard)
NoOfCardsTurnedOver = NoOfCardsTurnedOver + 1
Higher = IsNextCardHigher(LastCard, NextCard)
if (Higher and Choice == 'y') or (not Higher and Choice == 'n'):
DisplayCorrectGuessMessage(NoOfCardsTurnedOver - 1)
LastCard.Rank = NextCard.Rank
LastCard.Suit = NextCard.Suit
else:
#decrease number of lives by one
lives -=1
#checks if no lives remain
if lives==0:
GameOver=True
#prints number of lives remaining
else:
print ("incorrect", lives, "lives remaining")
if GameOver:
#changed way game calculates score
DisplayEndOfGameMessage(NoOfCardsTurnedOver - 4 + lives)
UpdateRecentScores(RecentScores, NoOfCardsTurnedOver - 4 + lives)
else:
DisplayEndOfGameMessage(51)
UpdateRecentScores(RecentScores, 51)
Java solution
Answer:
void playGame(TCard[] deck, TRecentScore[] recentScores) {
int noOfCardsTurnedOver;
boolean gameOver;
int counter = 2;
TCard nextCard;
TCard lastCard;
nextCard = new TCard();
lastCard = new TCard();
boolean higher;
char choice;
gameOver = false;
getCard(lastCard, deck, 0);
displayCard(lastCard);
noOfCardsTurnedOver = 1;
while (noOfCardsTurnedOver < 52 && !gameOver && counter>=1) {
getCard(nextCard, deck, noOfCardsTurnedOver);
do {
choice = getChoiceFromUser();
} while (!(choice == 'y' || choice == 'n' || choice == 'q'));
displayCard(nextCard);
noOfCardsTurnedOver = noOfCardsTurnedOver + 1;
higher = isNextCardHigher(lastCard, nextCard);
if (!higher && choice =='y' || higher && choice=='n') {
counter--;
console.println("Lives Left: " + counter);
}
if (higher && choice =='y' || !higher && choice=='n') {
displayCorrectGuessMessage(noOfCardsTurnedOver - 1);
lastCard.rank = nextCard.rank;
lastCard.suit = nextCard.suit;
}
if(counter<=0 || choice=='q') {
gameOver = true;
}
}
if (gameOver) {
displayEndOfGameMessage(noOfCardsTurnedOver - 2);
updateRecentScores(recentScores, noOfCardsTurnedOver - 2);
} else {
displayEndOfGameMessage(51);
updateRecentScores(recentScores, 51);
}
}
/* Dwarph+ Mr X */
Pascal solution
Answer:
//James Tarpy Longbenton Community College Newcastle upon Tyne
//solution requires changes to one Function and one Procedure
Function GetChoiceFromUser (var gameover : integer) : Char;
Var
Choice : Char;
Begin
Writeln('Do you think the next card will be higher than the last card (enter y or n)? ');
writeln(gameover, ' lives remaining');
Readln(Choice);
GetChoiceFromUser := Choice;
End;
Procedure PlayGame(Deck : TDeck; Var RecentScores : TRecentScores);
Var
NoOfCardsTurnedOver : Integer;
GameOver : integer;
LastCard : TCard;
NextCard : TCard;
Higher : Boolean;
Choice : Char;
Begin
GameOver := 3; //sets number of lives - you could make this a global constant defined at the start of the program is you want
GetCard(LastCard, Deck, 0);
DisplayCard(LastCard);
NoOfCardsTurnedOver := 1;
While (NoOfCardsTurnedOver < 52) And (GameOver>0)
Do
Begin
GetCard(NextCard, Deck, NoOfCardsTurnedOver);
Repeat
Choice := GetChoiceFromUser(gameover);
Until (Choice = 'y') Or (Choice = 'n');
DisplayCard(NextCard);
NoOfCardsTurnedOver := NoOfCardsTurnedOver + 1;
Higher := IsNextCardHigher(LastCard, NextCard);
If Higher And (Choice = 'y') Or Not Higher And (Choice = 'n')
Then
Begin
DisplayCorrectGuessMessage(NoOfCardsTurnedOver - 1);
LastCard := NextCard;
End
Else GameOver := gameover-1;
End;
If GameOver=0
Then
Begin
DisplayEndOfGameMessage(NoOfCardsTurnedOver - 2);
UpdateRecentScores(RecentScores, NoOfCardsTurnedOver - 2);
End
Else
Begin
DisplayEndOfGameMessage(51);
UpdateRecentScores(RecentScores, 51);
End
Replay a shuffled deck. Add a menu option to replay the last "shuffled" game.
editAs each card is thrown away and moved up the deck this requires changing the deck handling to include a pointer. Is this
Likely?
This does not appear to be needed. You can just replay with Deck as the contents of that are not lost. There is no need for a copy of the Deck to play again.
No it doesn't. As the person who produced the Pascal solution has shown - just take a copy of the shuffled deck before you start playing. You can play this copy again and again.
GetCard effectively pops card from deck and fills in a blank on bottom so destroys the deck while playing Python version available as well
VB.Net solution
Answer:
' add this code to sub Main()
Dim ShuffledDeck(52) As TCard
Case "1"
LoadDeck(Deck)
ShuffleDeck(Deck)
For i = 1 To 52 'question 14
ShuffledDeck(i) = Deck(i) 'question 14
Next 'question 14
PlayGame(Deck, RecentScores)
Case "7" 'question 14
For i = 1 To 52 'question 14
Deck(i) = ShuffledDeck(i) 'question 14
Next i 'question 14
PlayGame(Deck, RecentScores) 'question 14
' dont forget to add a line into sub DisplayMenu as well
' Mr Roberts YDT
Python Solution
Answer:
#Python solution
# Modify 2014 Python Skeleton code
# Paul Carpenter - PC Services
# Changes for menus for replay existing deck
# Involves copying array after shuffle, and copying back when replaying
# Only changed functions and code sections shown
# IMPORTANT module copy for copying arrays completely
import copy
#define GLOBAL for Deck and Copy
Deck = []
OldDeck = []
class TCard( ):
def __init__( self, suit=0, rank=0 ):
self.Suit = suit
self.Rank = rank
class TRecentScore( ):
def __init__( self, name='', val=0 ):
self.Name = name
self.Score = val
def DisplayMenu():
print()
print( 'MAIN MENU' )
print()
print( '1. Play game (with shuffle)' )
print( '2. Play game (without shuffle)')
print( '3. Display recent scores' )
print( '4. Reset recent scores' )
print( '7. Replay last shuffled deck' )
print()
print( 'Select an option from the menu (or enter q to quit): ', end='' )
if __name__ == '__main__':
for Count in range(1, 53):
Deck.append( TCard() )
for Count in range(1, NO_OF_RECENT_SCORES + 1):
RecentScores.append( TRecentScore() )
Choice = ''
while Choice != 'q':
DisplayMenu()
Choice = GetMenuChoice()
if Choice == '1':
LoadDeck( Deck )
ShuffleDeck( Deck )
OldDeck = copy.deepcopy( Deck )
PlayGame( Deck, RecentScores )
elif Choice == '2':
LoadDeck( Deck )
PlayGame( Deck, RecentScores )
elif Choice == '3':
DisplayRecentScores( RecentScores )
elif Choice == '4':
ResetRecentScores( RecentScores )
elif Choice == '7':
Deck = copy.deepcopy( OldDeck )
PlayGame( Deck, RecentScores )
Java solution
Answer:
public Main() {
char choice;
TCard[] deck = new TCard[53];
TRecentScore[] recentScores = new TRecentScore[NO_OF_RECENT_SCORES + 1];
for (int count = 1; count <= NO_OF_RECENT_SCORES; count++) {
recentScores[count] = new TRecentScore();
recentScores[count].name = "";
recentScores[count].score = 0;
}
do {
displayMenu();
choice = getMenuChoice();
switch (choice) {
case '1':
loadDeck(deck);
shuffleDeck(deck);
playGame(deck, recentScores);
break;
case '2':
loadDeck(deck);
playGame(deck, recentScores);
break;
case '3':
displayRecentScores(recentScores);
break;
case '4':
resetRecentScores(recentScores);
break;
/* Add new menu option for replaying last shuffle */
case '5':
loadDeck(deck);
playLastGame(deck);
playGame(deck, recentScores);
break;
}
} while (choice != 'q');
}
/* displayMenu() function */
void displayMenu() {
console.println();
console.println("MAIN MENU");
console.println();
console.println("1. Play game (with shuffle)");
console.println("2. Play game (without shuffle)");
console.println("3. Display recent scores");
console.println("4. Reset recent scores");
console.println("5. Play using the last shuffled deck"); // Add option to main menu
console.println();
console.print("Select an option from the menu (or enter q to quit): ");
}
/* shuffleDeck() function */
void shuffleDeck(TCard[] deck) {
int noOfSwaps;
int position1;
int position2;
TCard swapSpace;
swapSpace = new TCard();
int noOfSwapsMadeSoFar;
noOfSwaps = 1000;
for (noOfSwapsMadeSoFar = 1; noOfSwapsMadeSoFar <= noOfSwaps; noOfSwapsMadeSoFar++) {
position1 = random.nextInt(52) + 1;
position2 = random.nextInt(52) + 1;
swapSpace.rank = deck[position1].rank;
swapSpace.suit = deck[position1].suit;
deck[position1].rank = deck[position2].rank;
deck[position1].suit = deck[position2].suit;
deck[position2].rank = swapSpace.rank;
deck[position2].suit = swapSpace.suit;
}
// Create a new AQAWriteTextFile2014 tied to previousdeck.txt and have it replace instead of append
AQAWriteTextFile2014 writefile = new AQAWriteTextFile2014("previousdeck.txt", false);
// Write deck to file
for (int i = 1; i < deck.length; i++) {
writefile.writeToTextFile(String.valueOf(deck[i].rank));
writefile.writeToTextFile(String.valueOf(deck[i].suit));
}
writefile.closeFile(); // Close the file to free it up for any other methods' use
}
/* Create a new method called playLastGame */
void playLastGame(TCard[] deck) { // method takes the deck array as parameter
// Create a new AQAReadTextFile2014 and tie it to previousdeck.txt
AQAReadTextFile2014 readfile = new AQAReadTextFile2014("previousdeck.txt");
String line = ""; // Temporary storage for read lines
// Iterate through files and add to deck
for (int i = 1; i < deck.length; i++) {
line = readfile.readLine();
deck[i].rank = Integer.valueOf(line); // Convert to integer
line = readfile.readLine();
deck[i].suit = Integer.valueOf(line); // Convert to integer
}
readfile.closeFile(); // Close the file to free it up for any other method's use
}
/* Dan Foad */
Pascal solution
Answer:
//Solution
Case Choice Of
'1':
Begin
LoadDeck(Deck);
ShuffleDeck(Deck);
spareDeck := Deck; //copies the Deck
PlayGame(Deck, RecentScores);
End;
'2':
Begin
LoadDeck(Deck);
PlayGame(Deck, RecentScores);
End;
'3': DisplayRecentScores(RecentScores);
'4': ResetRecentScores(RecentScores);
'5': SaveRecentScores(RecentScores);
'6': LoadRecentScores(RecentScores);
'7': begin //replay
Deck:=spareDeck;
PlayGame(Deck, RecentScores);
end;
End; //of case statement
Create a gambling element where reaching a certain score earns you more money, based on a user bet.
editVB.Net solution
Answer:
Sub Bookies()
Dim Name As String = Initializer()
Dim Funds As Integer = 100
Dim Bet As Integer
Dim Deck(52) As TCard
Dim RecentScores(NoOfRecentScores) As TRecentScore
Dim Score As Integer
LoadDeck(Deck)
ShuffleDeck(Deck)
While Funds > 0
Bet = GetBet(Funds)
Score = PlayGame(Deck, RecentScores)
Console.WriteLine(CStr(Score))
Funds = UpdateFunds(Funds, Name, Score, Bet)
End While
Console.WriteLine("Unfortunateley you are out of money, press enter to return to the main menu")
End Sub
Function Initializer()
Console.WriteLine("WELCOME TO THE CASINO")
Console.WriteLine("Please enter your name:")
Dim Name As String = Console.ReadLine
Console.WriteLine("Thanks " + Name + ", you have £100 to bet")
Console.WriteLine("Here are the stakes:")
Console.WriteLine("3. If you score more than 2 you save your bet")
Console.WriteLine("4. If you score more than 5 you double your bet")
Console.WriteLine("5. If you score more than 10 you quadruple your bet")
Return Name
End Function
Function GetBet(ByRef Funds As Integer)
Console.WriteLine("Please enter your stake:")
Dim Bet As Integer = Console.ReadLine
Do While Bet > Funds
Console.WriteLine("You don't have enough money please enter a smaller bet")
Bet = Console.ReadLine
Loop
Return Bet
End Function
Function UpdateFunds(ByRef Funds As Integer, ByVal Name As String, ByVal Score As Integer, ByVal Bet As Integer)
If (2 < Score) And (Score <= 5) Then
Funds = Funds
Console.WriteLine("Well done " + Name + " you kept your bet")
ElseIf (5 < Score) And (Score <= 10) Then
Funds = Funds + (Bet * 2)
Console.WriteLine("Congratulations " + Name + " you doubled your bet")
ElseIf (10 < Score) Then
Funds = Funds + (Bet * 4)
Console.WriteLine("Congratulations " + Name + " you quadrupled your bet")
Else
Funds = Funds - Bet
Console.WriteLine("Unlucky " + Name + " you lost your bet")
End If
Console.WriteLine("Your funds are now £" + CStr(Funds))
Return Funds
End Function
'Change PlayGame to a function and change it to return NoOfCardsTurnedOver
Python Solution
Answer:
#Python Solution
Java solution
Answer:
//Solution
Pascal solution
Answer:
//Solution
The Ace could be considered as a high card or a low card. Change the value of the aces to make them the highest card.
editVB.Net solution
Answer:
Function GetRank(ByVal RankNo As Integer) As String
Dim Rank As String = ""
Select Case RankNo
Case 1 : Rank = "Two"
Case 2 : Rank = "Three"
Case 3 : Rank = "Four"
Case 4 : Rank = "Five"
Case 5 : Rank = "Six"
Case 6 : Rank = "Seven"
Case 7 : Rank = "Eight"
Case 8 : Rank = "Nine"
Case 9 : Rank = "Ten"
Case 10 : Rank = "Jack"
Case 11 : Rank = "Queen"
Case 12 : Rank = "King"
Case 13 : Rank = "Ace"
End Select
Return Rank
End Function
'NLS
'Alternate Idea could be to just alter the value in the IsNextCardHigher Function the cards are passed by value anyway
Function IsNextCardHigher(ByVal LastCard As TCard, ByVal NextCard As TCard) As Boolean
If NextCard.Rank = 1 Then
NextCard.Rank = 14
End If
If LastCard.Rank = 1 Then
LastCard.Rank = 14
End If
Dim Higher As Boolean
Higher = False
If NextCard.Rank = LastCard.Rank Then
If NextCard.Suit > LastCard.Suit Then
Higher = True
End If
End If
If NextCard.Rank > LastCard.Rank Then
Higher = True
End If
Return Higher
End Function
'RS
Python Solution
Answer:
def GetRank(RankNo):
Rank = ''
RankNo+=1
if RankNo == 14:
Rank = 'Ace'
elif RankNo == 2:
Rank = 'Two'
elif RankNo == 3:
Rank = 'Three'
# Two part solution 1- simplify the display of card rank/suit
# 2 - change order of array
# Paul Carpenter - PC Services
# Change GetRank and GetSuit to array of strings
# This can be done in ALL the languages
# This also makes changing Ace from low to HIGHEST card easier
# Move Ace in get rank to after King
# REMOVE FUNCTIONS GetRank and GetSuit
# Add following arrays and comments in their place
# First '' entry is to get around issue that code uses 1 as first index
# when Python starts at 0 (you could change '' to 'Error' for trapping problems)
GetRank = [ '', 'Ace', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', 'Jack', 'Queen', 'King' ]
GetSuit = [ '', 'Clubs', 'Diamonds', 'Hearts', 'Spades' ]
# Change function DisplayCard as follows
# Note we are just accessing the array of strings and no longer calling more functions
# un-necessarily with extra overhead and convolution.
def DisplayCard(ThisCard):
print()
print( 'Card is the', GetRank[ ThisCard.Rank ], 'of', GetSuit[ ThisCard.Suit] )
print()
Java solution
Answer:
boolean isNextCardHigher(TCard lastCard, TCard nextCard){
boolean higher;
higher = false;
//////////////////// FIXED SECTION ////////
if (lastCard.rank == 1){
lastCard.rank = 14;
}
if (nextCard.rank == 1){
nextCard.rank = 14;
}
///////////////////////////////////////////
if (nextCard.rank > lastCard.rank){
higher = true;
}
return higher;
}
/*Ishydadon*/
Pascal solution
Answer:
//Made by AK
Function GetRank(RankNo : Integer) : String;
Var
Rank : String;
Begin
Rank := '';
Case RankNo Of
1 : Rank := 'Two';
2 : Rank := 'Three';
3 : Rank := 'Four';
4 : Rank := 'Five';
5 : Rank := 'Six';
6 : Rank := 'Seven';
7 : Rank := 'Eight';
8 : Rank := 'Nine';
9 : Rank := 'Ten';
10 : Rank := 'Jack';
11 : Rank := 'Queen';
12 : Rank := 'King';
13 : Rank := 'Ace';
End;
GetRank := Rank;
End;
Allow user to save the whole game, including the current player pack and the recent scores, quit the program, then restart program and continue to play saved game/scores
editVB.Net solution
Answer:
'DATE: 26/05/2014
'AUTHOR: Kiran Joshi, The Queen Katherine School, Kendal
'NOTES:
'Firstly I think its less likely that this will come up due to the extensive modifications to the program as a whole and the structure of the "PlayGame" Subroutine but don't hold me to it.
'When you are mid game and want to quit you are able to quit the game by using char "q". Data for the game is stored in a text file called "SavedGame.txt" in the program directory.
'You can load a game by selecting "Option 5" at the menu.
'Anyways I have written two very simple routines "SaveGame" and "LoadSavedGame" and modified "PlayGame" , "GetChoiceFromUser", "DisplayMenu" and "Main"
'Im sure there must be a easier way of doing this.
'OVERVIEW:
'+ SaveGame & LoadSavedGame have been added as SubRoutines
'+ Load(bool) has been added as a parameter to PlayGame SubRoutine
'+ Main and DisplayMenu have been edited to include options to LoadSaveGame
'+ GetChoiceFromUser has been modified to give the option to quit and save
'+ PlayGame now allows you to quit game midway and automatically save by calling function SaveGame.
'STRUCTURE OF SAVE FILE
'104 Lines have been used to store Deck Data. 52 Suits and 52 Ranks = 104.
'6 Lines to store RecentScores(using the constant global var that AQA provided)
'2 Lines to store NextCard
'2 Lines to store LastCard
'1 Line to store Number of turned cards
'CODE:
'SaveGame SubRoutine
Sub SaveGame(ByVal Deck() As TCard, ByVal RecentScores() As TRecentScore, ByVal NextCard As TCard, ByVal LastCard As TCard, ByVal NumberOfCardsTurned As Integer)
Dim FileWriter As StreamWriter
Dim FilePath As String
FilePath = CurDir() & "\SavedGame.txt"
If File.Exists(FilePath) = True Then
File.Delete(FilePath)
End If
FileWriter = New StreamWriter(FilePath)
For index = 1 To 52 'First 104 lines used to store deck data.
FileWriter.WriteLine(Deck(index).Suit)
FileWriter.WriteLine(Deck(index).Rank)
Next
For index = 1 To NoOfRecentScores 'Uses Global variable introduced by AQA. 6 lines used for Recent Scores.
FileWriter.WriteLine(RecentScores(index).Name)
FileWriter.WriteLine(RecentScores(index).Score)
Next
FileWriter.WriteLine(NextCard.Suit) '2 Lines used for NextCard
FileWriter.WriteLine(NextCard.Rank)
FileWriter.WriteLine(LastCard.Suit) '2 Lines used for LastCard
FileWriter.WriteLine(LastCard.Rank)
FileWriter.WriteLine(NumberOfCardsTurned.ToString) '1 Line used to store NumberOfCardsTurned
FileWriter.Close() 'Close the StreamWriter. We wouldn't want a corrupt save game!
End Sub
'LoadSavedGame SubRoutine
Sub LoadSavedGame(ByRef Deck() As TCard, ByRef RecentScores() As TRecentScore, ByRef NextCard As TCard, ByRef LastCard As TCard, ByRef NumberOfCardsTurned As Integer)
Dim FileReader As StreamReader
Dim FilePath As String
FilePath = CurDir() & "\SavedGame.txt"
If File.Exists(FilePath) = True Then
FileReader = New StreamReader(FilePath)
For index = 1 To 52
Deck(index).Suit = FileReader.ReadLine
Deck(index).Rank = FileReader.ReadLine
Next
For index = 1 To NoOfRecentScores
RecentScores(index).Name = FileReader.ReadLine
RecentScores(index).Score = FileReader.ReadLine
Next
NextCard.Suit = FileReader.ReadLine
NextCard.Rank = FileReader.ReadLine
LastCard.Suit = FileReader.ReadLine
LastCard.Rank = FileReader.ReadLine
NumberOfCardsTurned = Convert.ToInt32(FileReader.ReadLine)
FileReader.Close()
Console.WriteLine("Loaded Game!")
Else
Console.WriteLine("No Savegame has been found! We will generate a new game instead.")
End If
End Sub
'NOTES:
'As explained in the Pascal Solution (thanks James Tarpy) cards are popped of the deck and removed. As the deck gets smaller all the spaces in the array at the bottom are replaced with 0s.
'For example:
'Ace of Spades, Five of Hearts, Two of Spades, Three of Clubs.
'would be stored as (Suit,Rank):
'4,1 3,5 4,2 1,3
'after popping off the first card you are left with
'4,2 1,3 0,0 0,0
'4,1 gets stored Last Card
'3,5 gets stored Next Card
'Cards move down etc
'3,5 moved to Last Card
'======================================MODIFIED CODE=====================================================
PlayGame SubRoutine:
Sub PlayGame(ByVal Deck() As TCard, ByRef RecentScores() As TRecentScore, ByVal LoadGame As Boolean)
'TAKE NOTE OF THE NEW PARAMETER "LOADGAME"
Dim NoOfCardsTurnedOver As Integer
Dim GameOver As Boolean
Dim NextCard As TCard
Dim LastCard As TCard
Dim Higher As Boolean
Dim Choice As Char
Dim UserQuit As Boolean = False
GameOver = False
GetCard(LastCard, Deck, 0)
NoOfCardsTurnedOver = 1
If LoadGame = True Then
LoadSavedGame(Deck, RecentScores, NextCard, LastCard, NoOfCardsTurnedOver)
End If
DisplayCard(LastCard) ' Moved down because otherwise you get an empty message from this routine!
While NoOfCardsTurnedOver < 52 And Not GameOver And Not UserQuit
GetCard(NextCard, Deck, NoOfCardsTurnedOver)
Do
Choice = GetChoiceFromUser()
Loop Until Choice = "y" Or Choice = "n" Or Choice = "q" 'NEW
DisplayCard(NextCard)
NoOfCardsTurnedOver = NoOfCardsTurnedOver + 1
Higher = IsNextCardHigher(LastCard, NextCard)
If Higher And Choice = "y" Or Not Higher And Choice = "n" Then
DisplayCorrectGuessMessage(NoOfCardsTurnedOver - 1)
LastCard = NextCard
ElseIf Choice = "q" Then 'NEW
UserQuit = True 'NEW
SaveGame(Deck, RecentScores, NextCard, LastCard, NoOfCardsTurnedOver) 'NEW
Else
GameOver = True
End If
End While
If GameOver Then
DisplayEndOfGameMessage(NoOfCardsTurnedOver - 2)
UpdateRecentScores(RecentScores, NoOfCardsTurnedOver - 2)
ElseIf UserQuit = True Then
Console.WriteLine("You have quit the game!") 'NEW
Else
DisplayEndOfGameMessage(51)
UpdateRecentScores(RecentScores, 51)
End If
End Sub
'GetChoiceFromUser SubRoutine:
Function GetChoiceFromUser() As Char
Dim Choice As Char
Console.WriteLine("Do you think the next card will be higher than the last card (enter y or n)? ")
Console.WriteLine("Enter q to save and quit")
Choice = Console.ReadLine
Return Choice
End Function
'Main Subroutine(TAKE NOTE OF PARAMETER CHANGES!):
Sub Main()
Dim Choice As Char
Dim Deck(52) As TCard
Dim RecentScores(NoOfRecentScores) As TRecentScore
Randomize()
Do
DisplayMenu()
Choice = GetMenuChoice()
Select Case Choice
Case "1"
LoadDeck(Deck)
ShuffleDeck(Deck)
PlayGame(Deck, RecentScores, False)
Case "2"
LoadDeck(Deck)
PlayGame(Deck, RecentScores, False)
Case "3"
DisplayRecentScores(RecentScores)
Case "4"
ResetRecentScores(RecentScores)
Case "5"
PlayGame(Deck, RecentScores, True)
End Select
Loop Until Choice = "q"
End Sub
'DisplayMenu Subroutine:
Console.WriteLine("5. Play game (Load saved game)") 'ADD THIS INTO DISPLAYMENU SUBROUTINE IN A LOGICAL POSITION
'Code written by Kiran Joshi
'The Queen Katherine School, Kendal
Python Solution
Answer:
#Python Solution
Java solution
Answer:
//Solution
Pascal solution
Answer:
//Solution
//James Tarpy Longbenton Community College Newcastle upon Tyne
//The two score save/load procedures can go anywhere amongst your Procedure declarations
//The savegame and loadsavedeck procedures can go anywhere amongst your procedure declarations
//DisplayCorrectGuess Message has been modified to ask the user “Do you want to save?” which then calls savegame
//PlayGame has been modified to make sure that recent scores are saved to file even if they lose
//A new case option has been added to the menu of choices in the main program - '5' load saved game - to call the loadsavegame procedures
//players can now load a game they saved either during the current game, or from a previous session
//===============================
procedure Savescores;
Var
ScoresFile : Text;
Index : Integer;
Begin
AssignFile(ScoresFile, 'C:\Users\James\Desktop\scores.txt'); // this is the file location/name on MY COMPUTER – you will need to set this up as required
Rewrite(ScoresFile);
For Index := 1 to NoOfRecentScores Do
Begin
Writeln(ScoresFile, RecentScores[index].Name);
Writeln(ScoresFile, RecentScores[index].Score);
End;
CloseFile(ScoresFile);
End;
//=========================================
procedure loadscores(var recentscore :TRecentScores);
Var
ScoresFile : Text;
CurrentScore : integer;
Index : Integer;
Begin
AssignFile(ScoresFile, 'C:\Users\James\Desktop\scores.txt'); // this is the file location/name on MY COMPUTER – you will need to set this up as required
Reset(ScoresFile);
For Index := 1 to NoOfRecentScores Do
Begin
Readln(ScoresFile, RecentScores[index].Name);
Readln(ScoresFile, CurrentScore); //some versions of PASCAL need strtoint here – mine (FPC) didn’t!
RecentScores[index].Score := CurrentScore;
End;
CloseFile(ScoresFile);
End;
//====================================
procedure savegame(var Deck : TDeck);
Var
Count : Integer;
CurrentFile : Text;
begin
Assign(CurrentFile, 'C:\Users\James\Desktop\save.txt');
rewrite(CurrentFile);
Count := 1;
While count<52
Do
Begin
writeln(currentfile, Deck[Count].Suit);
writeln(currentfile, Deck[Count].Rank);
Count := Count + 1;
End;
Close(CurrentFile);
end;
//=========================================
//Explanation-
//the Deck is held in a array of 52 records, each record holds a card's Suit and Rank
//as the game progresses cards are removed from the top of the deck, all cards are moved up one place, and 0,0 cards are fed into the bottom place.
//this procedure loads the content of save.txt into the Deck
//it counts the number of cards that are Rank 0. This equals thew number of cards turned over
//simple!
procedure loadsaveddeck (var deck :Tdeck; var numberofcardsturnedover:integer);
Var
Count : Integer;
CurrentFile : Text;
LineFromFile : String;
Err : Integer;
Begin
Assign(CurrentFile, 'C:\Users\James\Desktop\save.txt');
Reset(CurrentFile);
Count := 1;
numberofcardsturnedover:=0;
While Not EOF(CurrentFile)
Do
Begin
Readln(CurrentFile, LineFromFile);
Val(LineFromFile, Deck[Count].Suit, Err);
Readln(CurrentFile, LineFromFile);
Val(LineFromFile, Deck[Count].Rank, Err);
if (deck[count].rank)= 0 then
numberofcardsturnedover:= numberofcardsturnedover+1;
Count := Count + 1;
End;
Close(CurrentFile);
End;
//===================================
Procedure DisplayCorrectGuessMessage(Score : Integer; deck : Tdeck);
var
save : char;
loop : integer;
Begin
loop:=1;
Writeln;
Writeln('Well done! You guessed correctly.');
Writeln('Your score is now ', Score, '.');
Writeln;
while loop=1 Do //After displaying scores asks user to save
begin
writeln('Do you want to save? y/n');
readln(save);
if save='y' then
begin
savegame(Deck); //scores and deck are saved
savescores;
loop:=0;
end;
if save='n' then loop:=0
end;
loop:=1;
End;
//==========================================
Procedure PlayGame(Deck : TDeck; Var RecentScores : TRecentScores; numberofcardsturnedover : integer);
Var
GameOver : Boolean;
// LastCard and so on.....
//.................most of this is now the same as in original program apart from last few lines starting ....
If GameOver
Then
Begin
DisplayEndOfGameMessage(numberofcardsturnedover - 2);
UpdateRecentScores(RecentScores, numberofcardsturnedover - 2);
Savescores; //added extra save score even if they lose
End
Else
Begin
DisplayEndOfGameMessage(51);
UpdateRecentScores(RecentScores, 51);
End;
End;
//################ this is the new main program
Begin
numberofcardsturnedover:=0;
Randomize;
Repeat
DisplayMenu;
Choice := GetMenuChoice;
Case Choice Of
'1':
Begin
LoadDeck(Deck);
ShuffleDeck(Deck);
PlayGame(Deck, RecentScores, 0);
End;
'2':
Begin
LoadDeck(Deck);
PlayGame(Deck, RecentScores, 0);
End;
'3': DisplayRecentScores(RecentScores);
'4': ResetRecentScores(RecentScores);
'5': //this is the new option
begin
loadsaveddeck(deck,numberofcardsturnedover);
playgame(deck, recentscores, numberofcardsturnedover);
end;
End;
Until Choice = 'q';
End.
When the card number is the same you draw and go onto the next card instead of losing.
editBasically change IsNextCardHigher to become IsNextCardHigherOrEqual
VB.Net solution
Answer:
Function IsNextCardHigher(ByVal LastCard As TCard, ByVal NextCard As TCard) As Boolean
Dim Higher As Boolean = False
If NextCard.Rank = LastCard.Rank Then
If NextCard.Suit > LastCard.Suit Then
Higher = True
End If
Else
If NextCard.Rank >= LastCard.Rank Then 'Changed > to >=
Higher = True
End If
End If
Return Higher
End Function
Python Solution
Answer:
# PAul Carpenter - PC Services
# To create a draw situation and carry on
# function becomes effectively "is next card higher OR EQUAL
def IsNextCardHigher(LastCard, NextCard):
Higher = False
# Change ">" to ">="
if NextCard.Rank >= LastCard.Rank:
Higher = True
return Higher
Java solution
Answer:
void playGame(TCard[] deck, TRecentScore[] recentScores) {
int noOfCardsTurnedOver;
boolean gameOver;
TCard nextCard;
TCard lastCard;
nextCard = new TCard();
lastCard = new TCard();
boolean higher;
char choice;
gameOver = false;
getCard(lastCard, deck, 0);
displayCard(lastCard);
noOfCardsTurnedOver = 1;
while (noOfCardsTurnedOver < 52 && !gameOver) {
getCard(nextCard, deck, noOfCardsTurnedOver);
do {
choice = getChoiceFromUser();
} while (!(choice == 'y' || choice == 'n'));
displayCard(nextCard);
noOfCardsTurnedOver = noOfCardsTurnedOver + 1;
higher = isNextCardHigher(lastCard, nextCard);
/* Add additional clause to if statement to check for draw */
if (lastCard.rank == nextCard.rank) { // Check if draw
wasDraw(noOfCardsTurnedOver - 1); // Call the created wasDraw() method
// Move onto next card
lastCard.rank = nextCard.rank;
lastCard.suit = nextCard.suit;
/* End added clause. Make sure to have it be the first checked */
} else if (higher && choice =='y' || !higher && choice=='n') {
displayCorrectGuessMessage(noOfCardsTurnedOver - 1);
lastCard.rank = nextCard.rank;
lastCard.suit = nextCard.suit;
} else {
gameOver = true;
}
}
if (gameOver) {
displayEndOfGameMessage(noOfCardsTurnedOver - 2);
updateRecentScores(recentScores, noOfCardsTurnedOver - 2);
} else {
displayEndOfGameMessage(51);
updateRecentScores(recentScores, 51);
}
}
/* Create new wasDraw method */
void wasDraw(int score) {
console.println("It's a draw! You get a free point."); // You can print whatever to indicate it was a draw
console.printf("Your score is now %s.\r\n", score); // Print score again
console.println();
}
/* Dan Foad */
Pascal solution
Answer:
//Solution
Make a two player game. Instead of 'Game over' play passes to the other player. Last man standing when the deck is exhausted wins. Or they get 5 guesses each, top score wins./*Surely the scores will be the same if no-one's got it wrong after 5?*/ /*If so, continue*/
editVB.Net solution
Answer:
Python Solution
Answer:
#Python Solution
Java solution
Answer:
//Solution
Pascal solution
Answer:
//Solution
When displaying the scores sort the player names into alphabetical order regardless of score
editVB.Net solution
Answer:
Python Solution
Answer:
#Python Solution
Java solution
Answer:
//Solution
Pascal solution
Answer:
//Solution
If you turn over 51 cards shuffle the deck and continue playing
editCode provided by AQA is linked here
editVB.NET
Answer:
'Skeleton Program code for the AQA COMP1 Summer 2014 examination
'this code should be used in conjunction with the Preliminary Material
'written by the AQA COMP1 Programmer Team
'developed in the Visual Studio 2008 (Console Mode) programming environment (VB.NET)
Module CardPredict
Const NoOfRecentScores As Integer = 3
Structure TCard
Dim Suit As Integer
Dim Rank As Integer
End Structure
Structure TRecentScore
Dim Name As String
Dim Score As Integer
End Structure
Sub Main()
Dim Choice As Char
Dim Deck(52) As TCard
Dim RecentScores(NoOfRecentScores) As TRecentScore
Randomize()
Do
DisplayMenu()
Choice = GetMenuChoice()
Select Case Choice
Case "1"
LoadDeck(Deck)
ShuffleDeck(Deck)
PlayGame(Deck, RecentScores)
Case "2"
LoadDeck(Deck)
PlayGame(Deck, RecentScores)
Case "3"
DisplayRecentScores(RecentScores)
Case "4"
ResetRecentScores(RecentScores)
End Select
Loop Until Choice = "q"
End Sub
Function GetRank(ByVal RankNo As Integer) As String
Dim Rank As String = ""
Select Case RankNo
Case 1 : Rank = "Ace"
Case 2 : Rank = "Two"
Case 3 : Rank = "Three"
Case 4 : Rank = "Four"
Case 5 : Rank = "Five"
Case 6 : Rank = "Six"
Case 7 : Rank = "Seven"
Case 8 : Rank = "Eight"
Case 9 : Rank = "Nine"
Case 10 : Rank = "Ten"
Case 11 : Rank = "Jack"
Case 12 : Rank = "Queen"
Case 13 : Rank = "King"
End Select
Return Rank
End Function
Function GetSuit(ByVal SuitNo As Integer) As String
Dim Suit As String = ""
Select Case SuitNo
Case 1 : Suit = "Clubs"
Case 2 : Suit = "Diamonds"
Case 3 : Suit = "Hearts"
Case 4 : Suit = "Spades"
End Select
Return Suit
End Function
Sub DisplayMenu()
Console.WriteLine()
Console.WriteLine("MAIN MENU")
Console.WriteLine()
Console.WriteLine("1. Play game (with shuffle)")
Console.WriteLine("2. Play game (without shuffle)")
Console.WriteLine("3. Display recent scores")
Console.WriteLine("4. Reset recent scores")
Console.WriteLine()
Console.Write("Select an option from the menu (or enter q to quit): ")
End Sub
Function GetMenuChoice() As Char
Dim Choice As Char
Choice = Console.ReadLine
Console.WriteLine()
Return Choice
End Function
Sub LoadDeck(ByRef Deck() As TCard)
Dim Count As Integer
FileOpen(1, "deck.txt", OpenMode.Input)
Count = 1
While Not EOF(1)
Deck(Count).Suit = CInt(LineInput(1))
Deck(Count).Rank = CInt(LineInput(1))
Count = Count + 1
End While
FileClose(1)
End Sub
Sub ShuffleDeck(ByRef Deck() As TCard)
Dim NoOfSwaps As Integer
Dim Position1 As Integer
Dim Position2 As Integer
Dim SwapSpace As TCard
Dim NoOfSwapsMadeSoFar As Integer
NoOfSwaps = 1000
For NoOfSwapsMadeSoFar = 1 To NoOfSwaps
Position1 = Int(Rnd() * 52) + 1
Position2 = Int(Rnd() * 52) + 1
SwapSpace = Deck(Position1)
Deck(Position1) = Deck(Position2)
Deck(Position2) = SwapSpace
Next
End Sub
Sub DisplayCard(ByVal ThisCard As TCard)
Console.WriteLine()
Console.WriteLine("Card is the " & GetRank(ThisCard.Rank) & " of " & GetSuit(ThisCard.Suit))
Console.WriteLine()
End Sub
Sub GetCard(ByRef ThisCard As TCard, ByRef Deck() As TCard, ByVal NoOfCardsTurnedOver As Integer)
Dim Count As Integer
ThisCard = Deck(1)
For Count = 1 To (51 - NoOfCardsTurnedOver)
Deck(Count) = Deck(Count + 1)
Next
Deck(52 - NoOfCardsTurnedOver).Suit = 0
Deck(52 - NoOfCardsTurnedOver).Rank = 0
End Sub
Function IsNextCardHigher(ByVal LastCard As TCard, ByVal NextCard As TCard) As Boolean
Dim Higher As Boolean
Higher = False
If NextCard.Rank > LastCard.Rank Then
Higher = True
End If
Return Higher
End Function
Function GetPlayerName() As String
Dim PlayerName As String
Console.WriteLine()
Console.Write("Please enter your name: ")
PlayerName = Console.ReadLine
Console.WriteLine()
Return PlayerName
End Function
Function GetChoiceFromUser() As Char
Dim Choice As Char
Console.Write("Do you think the next card will be higher than the last card (enter y or n)? ")
Choice = Console.ReadLine
Return Choice
End Function
Sub DisplayEndOfGameMessage(ByVal Score As Integer)
Console.WriteLine()
Console.WriteLine("GAME OVER!")
Console.WriteLine("Your score was " & Score)
If Score = 51 Then
Console.WriteLine("WOW! You completed a perfect game.")
End If
Console.WriteLine()
End Sub
Sub DisplayCorrectGuessMessage(ByVal Score As Integer)
Console.WriteLine()
Console.WriteLine("Well done! You guessed correctly.")
Console.WriteLine("Your score is now " & Score & ".")
Console.WriteLine()
End Sub
Sub ResetRecentScores(ByRef RecentScores() As TRecentScore)
Dim Count As Integer
For Count = 1 To NoOfRecentScores
RecentScores(Count).Name = ""
RecentScores(Count).Score = 0
Next
End Sub
Sub DisplayRecentScores(ByVal RecentScores() As TRecentScore)
Dim Count As Integer
Console.WriteLine()
Console.WriteLine("Recent scores:")
Console.WriteLine()
For Count = 1 To NoOfRecentScores
Console.WriteLine(RecentScores(Count).Name & " got a score of " & RecentScores(Count).Score)
Next
Console.WriteLine()
Console.WriteLine("Press the Enter key to return to the main menu")
Console.WriteLine()
Console.ReadLine()
End Sub
Sub UpdateRecentScores(ByRef RecentScores() As TRecentScore, ByVal Score As Integer)
Dim PlayerName As String
Dim Count As Integer
Dim FoundSpace As Boolean
PlayerName = GetPlayerName()
FoundSpace = False
Count = 1
While Not FoundSpace And Count <= NoOfRecentScores
If RecentScores(Count).Name = "" Then
FoundSpace = True
Else
Count = Count + 1
End If
End While
If Not FoundSpace Then
For Count = 1 To NoOfRecentScores - 1
RecentScores(Count) = RecentScores(Count + 1)
Next
Count = NoOfRecentScores
End If
RecentScores(Count).Name = PlayerName
RecentScores(Count).Score = Score
End Sub
Sub PlayGame(ByVal Deck() As TCard, ByRef RecentScores() As TRecentScore)
Dim NoOfCardsTurnedOver As Integer
Dim GameOver As Boolean
Dim NextCard As TCard
Dim LastCard As TCard
Dim Higher As Boolean
Dim Choice As Char
GameOver = False
GetCard(LastCard, Deck, 0)
DisplayCard(LastCard)
NoOfCardsTurnedOver = 1
While NoOfCardsTurnedOver < 52 And Not GameOver
GetCard(NextCard, Deck, NoOfCardsTurnedOver)
Do
Choice = GetChoiceFromUser()
Loop Until Choice = "y" Or Choice = "n"
DisplayCard(NextCard)
NoOfCardsTurnedOver = NoOfCardsTurnedOver + 1
Higher = IsNextCardHigher(LastCard, NextCard)
If Higher And Choice = "y" Or Not Higher And Choice = "n" Then
DisplayCorrectGuessMessage(NoOfCardsTurnedOver - 1)
LastCard = NextCard
Else
GameOver = True
End If
End While
If GameOver Then
DisplayEndOfGameMessage(NoOfCardsTurnedOver - 2)
UpdateRecentScores(RecentScores, NoOfCardsTurnedOver - 2)
Else
DisplayEndOfGameMessage(51)
UpdateRecentScores(RecentScores, 51)
End If
End Sub
End Module
Java
Answer:
/**
* JAVA
* Skeleton Program code for the AQA COMP1 Summer 2014 examination
* This code should be used in conjunction with the Preliminary Material
* written by the AQA Programmer Team developed in the Netbeans 6.9.1 IDE
* Additional classes AQAConsole2014, AQAReadTextFile2014 and
* AQAWriteTextFile2014 may be used.
*
* A package name may be chosen and private and public modifiers added.
* Permission to make these changes to the Skeleton Program does not
* need to be obtained from AQA/AQA Programmer
*/
import java.util.Random;
public class Main {
AQAConsole2014 console = new AQAConsole2014();
final int NO_OF_RECENT_SCORES = 3;
Random random = new Random();
class TCard {
int suit;
int rank;
}
class TRecentScore {
String name;
int score;
}
public Main() {
char choice;
TCard[] deck = new TCard[53];
TRecentScore[] recentScores = new TRecentScore[NO_OF_RECENT_SCORES + 1];
for (int count = 1; count <= NO_OF_RECENT_SCORES; count++) {
recentScores[count] = new TRecentScore();
recentScores[count].name = "";
recentScores[count].score = 0;
}
do {
displayMenu();
choice = getMenuChoice();
switch (choice) {
case '1':
loadDeck(deck);
shuffleDeck(deck);
playGame(deck, recentScores);
break;
case '2':
loadDeck(deck);
playGame(deck, recentScores);
break;
case '3':
displayRecentScores(recentScores);
break;
case '4':
resetRecentScores(recentScores);
break;
}
} while (choice != 'q');
}
String getRank(int rankNo) {
String rank = "";
switch (rankNo) {
case 1:
rank = "Ace";
break;
case 2:
rank = "Two";
break;
case 3:
rank = "Three";
break;
case 4:
rank = "Four";
break;
case 5:
rank = "Five";
break;
case 6:
rank = "Six";
break;
case 7:
rank = "Seven";
break;
case 8:
rank = "Eight";
break;
case 9:
rank = "Nine";
break;
case 10:
rank = "Ten";
break;
case 11:
rank = "Jack";
break;
case 12:
rank = "Queen";
break;
case 13:
rank = "King";
break;
}
return rank;
}
String getSuit(int suitNo) {
String suit = "";
switch (suitNo) {
case 1:
suit = "Clubs";
break;
case 2:
suit = "Diamonds";
break;
case 3:
suit = "Hearts";
break;
case 4:
suit = "Spades";
break;
}
return suit;
}
void displayMenu() {
console.println();
console.println("MAIN MENU");
console.println();
console.println("1. Play game (with shuffle)");
console.println("2. Play game (without shuffle)");
console.println("3. Display recent scores");
console.println("4. Reset recent scores");
console.println();
console.print("Select an option from the menu (or enter q to quit): ");
}
char getMenuChoice() {
char choice;
choice = console.readChar();
console.println();
return choice;
}
void loadDeck(TCard[] deck) {
int count;
for (count = 1; count <= 52; count++) {
deck[count] = new TCard();
deck[count].suit = 0;
deck[count].rank = 0;
}
String lineFromFile;
AQAReadTextFile2014 currentFile;
currentFile = new AQAReadTextFile2014();
currentFile.openTextFile("deck.txt");
count = 1;
lineFromFile = currentFile.readLine();
while (lineFromFile != null) {
deck[count].suit = Integer.parseInt(lineFromFile);
lineFromFile = currentFile.readLine();
deck[count].rank = Integer.parseInt(lineFromFile);
lineFromFile = currentFile.readLine();
count = count + 1;
}
currentFile.closeFile();
}
void shuffleDeck(TCard[] deck) {
int noOfSwaps;
int position1;
int position2;
TCard swapSpace;
swapSpace = new TCard();
int noOfSwapsMadeSoFar;
noOfSwaps = 1000;
for (noOfSwapsMadeSoFar = 1; noOfSwapsMadeSoFar <= noOfSwaps; noOfSwapsMadeSoFar++) {
position1 = random.nextInt(52) + 1;
position2 = random.nextInt(52) + 1;
swapSpace.rank = deck[position1].rank;
swapSpace.suit = deck[position1].suit;
deck[position1].rank = deck[position2].rank;
deck[position1].suit = deck[position2].suit;
deck[position2].rank = swapSpace.rank;
deck[position2].suit = swapSpace.suit;
}
}
void displayCard(TCard thisCard) {
console.println();
console.print("Card is the ");
console.print(getRank(thisCard.rank));
console.print(" of ");
console.println(getSuit(thisCard.suit));
console.println();
}
void getCard(TCard thisCard, TCard[] deck, int noOfCardsTurnedOver) {
int count;
thisCard.rank = deck[1].rank;
thisCard.suit = deck[1].suit;
for (count = 1; count <= (51 - noOfCardsTurnedOver); count++) {
deck[count].rank = deck[count + 1].rank;
deck[count].suit = deck[count + 1].suit;
}
deck[52 - noOfCardsTurnedOver].suit = 0;
deck[52 - noOfCardsTurnedOver].rank = 0;
}
boolean isNextCardHigher(TCard lastCard, TCard nextCard){
boolean higher;
higher = false;
if (nextCard.rank > lastCard.rank){
higher = true;
}
return higher;
}
String getPlayerName() {
String playerName = "";
console.println();
playerName = console.readLine("Please enter your name: ");
console.println();
return playerName;
}
char getChoiceFromUser() {
char choice;
choice = console.readChar("Do you think the next card will be higher than the last card (enter y or n)? ");
return choice;
}
void displayEndOfGameMessage(int score) {
console.println();
console.println("GAME OVER!");
console.print("Your score was ");
console.println(score);
if (score == 51) {
console.println("WOW! You completed a perfect game.");
}
console.println();
}
void displayCorrectGuessMessage(int score) {
console.println();
console.println("Well done! You guessed correctly.");
console.print("Your score is now ");
console.print(score);
console.println(".");
console.println();
}
void resetRecentScores(TRecentScore[] recentScores) {
int count;
for (count = 1; count <= NO_OF_RECENT_SCORES; count++) {
recentScores[count].name = "";
recentScores[count].score = 0;
}
}
void displayRecentScores(TRecentScore[] recentScores) {
int count;
console.println();
console.println("Recent scores:");
console.println();
for (count = 1; count <= NO_OF_RECENT_SCORES; count++) {
console.print(recentScores[count].name);
console.print(" got a score of ");
console.println(recentScores[count].score);
}
console.println();
console.println("Press the Enter key to return to the main menu");
console.println();
console.readLine();
}
void updateRecentScores(TRecentScore[] recentScores, int score) {
String playerName;
int count;
boolean foundSpace;
playerName = getPlayerName();
foundSpace = false;
count = 1;
while (!foundSpace && count <= NO_OF_RECENT_SCORES) {
if (recentScores[count].name.equals("")) {
foundSpace = true;
} else {
count = count + 1;
}
}
if (!foundSpace) {
for (count = 1; count <= NO_OF_RECENT_SCORES - 1; count++) {
recentScores[count].name = recentScores[count + 1].name;
recentScores[count].score = recentScores[count + 1].score;
}
count = NO_OF_RECENT_SCORES;
}
recentScores[count].name = playerName;
recentScores[count].score = score;
}
void playGame(TCard[] deck, TRecentScore[] recentScores) {
int noOfCardsTurnedOver;
boolean gameOver;
TCard nextCard;
TCard lastCard;
nextCard = new TCard();
lastCard = new TCard();
boolean higher;
char choice;
gameOver = false;
getCard(lastCard, deck, 0);
displayCard(lastCard);
noOfCardsTurnedOver = 1;
while (noOfCardsTurnedOver < 52 && !gameOver) {
getCard(nextCard, deck, noOfCardsTurnedOver);
do {
choice = getChoiceFromUser();
} while (!(choice == 'y' || choice == 'n'));
displayCard(nextCard);
noOfCardsTurnedOver = noOfCardsTurnedOver + 1;
higher = isNextCardHigher(lastCard, nextCard);
if (higher && choice =='y' || !higher && choice=='n') {
displayCorrectGuessMessage(noOfCardsTurnedOver - 1);
lastCard.rank = nextCard.rank;
lastCard.suit = nextCard.suit;
} else {
gameOver = true;
}
}
if (gameOver) {
displayEndOfGameMessage(noOfCardsTurnedOver - 2);
updateRecentScores(recentScores, noOfCardsTurnedOver - 2);
} else {
displayEndOfGameMessage(51);
updateRecentScores(recentScores, 51);
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
new Main();
}
}
Python
Answer:
# Skeleton Program code for the AQA COMP1 Summer 2014 examination
# this code should be used in conjunction with the Preliminary Material
# written by the AQA Programmer Team
# developed in the Python 3.2 programming environment
# version 2 edited 06/03/2014
import random
NO_OF_RECENT_SCORES = 3
class TCard():
def __init__(self):
self.Suit = 0
self.Rank = 0
class TRecentScore():
def __init__(self):
self.Name = ''
self.Score = 0
Deck = [None]
RecentScores = [None]
Choice = ''
def GetRank(RankNo):
Rank = ''
if RankNo == 1:
Rank = 'Ace'
elif RankNo == 2:
Rank = 'Two'
elif RankNo == 3:
Rank = 'Three'
elif RankNo == 4:
Rank = 'Four'
elif RankNo == 5:
Rank = 'Five'
elif RankNo == 6:
Rank = 'Six'
elif RankNo == 7:
Rank = 'Seven'
elif RankNo == 8:
Rank = 'Eight'
elif RankNo == 9:
Rank = 'Nine'
elif RankNo == 10:
Rank = 'Ten'
elif RankNo == 11:
Rank = 'Jack'
elif RankNo == 12:
Rank = 'Queen'
elif RankNo == 13:
Rank = 'King'
return Rank
def GetSuit(SuitNo):
Suit = ''
if SuitNo == 1:
Suit = 'Clubs'
elif SuitNo == 2:
Suit = 'Diamonds'
elif SuitNo == 3:
Suit = 'Hearts'
elif SuitNo == 4:
Suit = 'Spades'
return Suit
def DisplayMenu():
print()
print('MAIN MENU')
print()
print('1. Play game (with shuffle)')
print('2. Play game (without shuffle)')
print('3. Display recent scores')
print('4. Reset recent scores')
print()
print('Select an option from the menu (or enter q to quit): ', end='')
def GetMenuChoice():
Choice = input()
print()
return Choice
def LoadDeck(Deck):
CurrentFile = open('deck.txt', 'r')
Count = 1
while True:
LineFromFile = CurrentFile.readline()
if not LineFromFile:
CurrentFile.close()
break
Deck[Count].Suit = int(LineFromFile)
LineFromFile = CurrentFile.readline()
Deck[Count].Rank = int(LineFromFile)
Count = Count + 1
def ShuffleDeck(Deck):
SwapSpace = TCard()
NoOfSwaps = 1000
for NoOfSwapsMadeSoFar in range(1, NoOfSwaps + 1):
Position1 = random.randint(1, 52)
Position2 = random.randint(1, 52)
SwapSpace.Rank = Deck[Position1].Rank
SwapSpace.Suit = Deck[Position1].Suit
Deck[Position1].Rank = Deck[Position2].Rank
Deck[Position1].Suit = Deck[Position2].Suit
Deck[Position2].Rank = SwapSpace.Rank
Deck[Position2].Suit = SwapSpace.Suit
def DisplayCard(ThisCard):
print()
print('Card is the', GetRank(ThisCard.Rank), 'of', GetSuit(ThisCard.Suit))
print()
def GetCard(ThisCard, Deck, NoOfCardsTurnedOver):
ThisCard.Rank = Deck[1].Rank
ThisCard.Suit = Deck[1].Suit
for Count in range(1, 52 - NoOfCardsTurnedOver):
Deck[Count].Rank = Deck[Count + 1].Rank
Deck[Count].Suit = Deck[Count + 1].Suit
Deck[52 - NoOfCardsTurnedOver].Suit = 0
Deck[52 - NoOfCardsTurnedOver].Rank = 0
def IsNextCardHigher(LastCard, NextCard):
Higher = False
if NextCard.Rank > LastCard.Rank:
Higher = True
return Higher
def GetPlayerName():
print()
PlayerName = input('Please enter your name: ')
print()
return PlayerName
def GetChoiceFromUser():
Choice = input('Do you think the next card will be higher than the last card (enter y or n)? ')
return Choice
def DisplayEndOfGameMessage(Score):
print()
print('GAME OVER!')
print('Your score was', Score)
if Score == 51:
print('WOW! You completed a perfect game.')
print()
def DisplayCorrectGuessMessage(Score):
print()
print('Well done! You guessed correctly.')
print('Your score is now ', Score, '.', sep='')
print()
def ResetRecentScores(RecentScores):
for Count in range(1, NO_OF_RECENT_SCORES + 1):
RecentScores[Count].Name = ''
RecentScores[Count].Score = 0
def DisplayRecentScores(RecentScores):
print()
print('Recent Scores: ')
print()
for Count in range(1, NO_OF_RECENT_SCORES + 1):
print(RecentScores[Count].Name, 'got a score of', RecentScores[Count].Score)
print()
print('Press the Enter key to return to the main menu')
input()
print()
def UpdateRecentScores(RecentScores, Score):
PlayerName = GetPlayerName()
FoundSpace = False
Count = 1
while (not FoundSpace) and (Count <= NO_OF_RECENT_SCORES):
if RecentScores[Count].Name == '':
FoundSpace = True
else:
Count = Count + 1
if not FoundSpace:
for Count in range(1, NO_OF_RECENT_SCORES):
RecentScores[Count].Name = RecentScores[Count + 1].Name
RecentScores[Count].Score = RecentScores[Count + 1].Score
Count = NO_OF_RECENT_SCORES
RecentScores[Count].Name = PlayerName
RecentScores[Count].Score = Score
def PlayGame(Deck, RecentScores):
LastCard = TCard()
NextCard = TCard()
GameOver = False
GetCard(LastCard, Deck, 0)
DisplayCard(LastCard)
NoOfCardsTurnedOver = 1
while (NoOfCardsTurnedOver < 52) and (not GameOver):
GetCard(NextCard, Deck, NoOfCardsTurnedOver)
Choice = ''
while (Choice != 'y') and (Choice != 'n'):
Choice = GetChoiceFromUser()
DisplayCard(NextCard)
NoOfCardsTurnedOver = NoOfCardsTurnedOver + 1
Higher = IsNextCardHigher(LastCard, NextCard)
if (Higher and Choice == 'y') or (not Higher and Choice == 'n'):
DisplayCorrectGuessMessage(NoOfCardsTurnedOver - 1)
LastCard.Rank = NextCard.Rank
LastCard.Suit = NextCard.Suit
else:
GameOver = True
if GameOver:
DisplayEndOfGameMessage(NoOfCardsTurnedOver - 2)
UpdateRecentScores(RecentScores, NoOfCardsTurnedOver - 2)
else:
DisplayEndOfGameMessage(51)
UpdateRecentScores(RecentScores, 51)
if __name__ == '__main__':
for Count in range(1, 53):
Deck.append(TCard())
for Count in range(1, NO_OF_RECENT_SCORES + 1):
RecentScores.append(TRecentScore())
Choice = ''
while Choice != 'q':
DisplayMenu()
Choice = GetMenuChoice()
if Choice == '1':
LoadDeck(Deck)
ShuffleDeck(Deck)
PlayGame(Deck, RecentScores)
elif Choice == '2':
LoadDeck(Deck)
PlayGame(Deck, RecentScores)
elif Choice == '3':
DisplayRecentScores(RecentScores)
elif Choice ==4:
ResetRecentScores(RecentScores)
Pascal
Answer:
Program CardPredict;
{Skeleton Program code for the AQA COMP1 Summer 2014 examination
this code should be used in conjunction with the Preliminary Material
written by the AQA COMP1 Programmer Team
developed in the Turbo Pascal 7 programming environment}
{Centres may also add the SysUtils library if their version of Pascal uses this}
{Permission to make this change to the Skeleton Program does not
need to be obtained from AQA/AQA Programmer - just remove braces around Uses SysUtils;}
{Uses
SysUtils;}
Const NoOfRecentScores = 3;
Type
TCard = Record
Suit : Integer;
Rank : Integer;
End;
TRecentScore = Record
Name : String;
Score : Integer;
End;
TDeck = Array[1..52] of TCard;
TRecentScores = Array[1..NoOfRecentScores] of TRecentScore;
Var
Choice : Char;
Deck : TDeck;
RecentScores : TRecentScores;
Function GetRank(RankNo : Integer) : String;
Var
Rank : String;
Begin
Rank := '';
Case RankNo Of
1 : Rank := 'Ace';
2 : Rank := 'Two';
3 : Rank := 'Three';
4 : Rank := 'Four';
5 : Rank := 'Five';
6 : Rank := 'Six';
7 : Rank := 'Seven';
8 : Rank := 'Eight';
9 : Rank := 'Nine';
10 : Rank := 'Ten';
11 : Rank := 'Jack';
12 : Rank := 'Queen';
13 : Rank := 'King';
End;
GetRank := Rank;
End;
Function GetSuit(SuitNo : Integer) : String;
Var
Suit : String;
Begin
Suit := '';
Case SuitNo Of
1 : Suit := 'Clubs';
2 : Suit := 'Diamonds';
3 : Suit := 'Hearts';
4 : Suit := 'Spades';
End;
GetSuit := Suit;
End;
Procedure DisplayMenu;
Begin
Writeln;
Writeln('MAIN MENU');
Writeln;
Writeln('1. Play game (with shuffle)');
Writeln('2. Play game (without shuffle)');
Writeln('3. Display recent scores');
Writeln('4. Reset recent scores');
Writeln;
Write('Select an option from the menu (or enter q to quit): ');
End;
Function GetMenuChoice : Char;
Var
Choice : Char;
Begin
Readln(Choice);
Writeln;
GetMenuChoice := Choice;
End;
Procedure LoadDeck(Var Deck : TDeck);
Var
Count : Integer;
CurrentFile : Text;
LineFromFile : String;
Err : Integer;
Begin
Assign(CurrentFile, '../deck.txt');
Reset(CurrentFile);
Count := 1;
While Not EOF(CurrentFile)
Do
Begin
Readln(CurrentFile, LineFromFile);
Val(LineFromFile, Deck[Count].Suit, Err);
Readln(CurrentFile, LineFromFile);
Val(LineFromFile, Deck[Count].Rank, Err);
Count := Count + 1;
End;
Close(CurrentFile);
End;
Procedure ShuffleDeck(Var Deck : TDeck);
Var
NoOfSwaps : Integer;
Position1 : Integer;
Position2 : Integer;
SwapSpace : TCard;
NoOfSwapsMadeSoFar : Integer;
Begin
NoOfSwaps := 1000;
For NoOfSwapsMadeSoFar := 1 To NoOfSwaps
Do
Begin
Position1 := Random(52) + 1;
Position2 := Random(52) + 1;
SwapSpace := Deck[Position1];
Deck[Position1] := Deck[Position2];
Deck[Position2] := SwapSpace;
End;
End;
Procedure DisplayCard(ThisCard : TCard);
Begin
Writeln;
Writeln('Card is the ', GetRank(ThisCard.Rank), ' of ', GetSuit(ThisCard.Suit));
Writeln;
End;
Procedure GetCard(Var ThisCard : TCard; Var Deck : TDeck; NoOfCardsTurnedOver : Integer);
Var
Count : Integer;
Begin
ThisCard := Deck[1];
For Count := 1 To (51 - NoOfCardsTurnedOver)
Do Deck[Count] := Deck[Count + 1];
Deck[52 - NoOfCardsTurnedOver].Suit := 0;
Deck[52 - NoOfCardsTurnedOver].Rank := 0;
End;
Function IsNextCardHigher(LastCard, NextCard : TCard) : Boolean;
Var
Higher : Boolean;
Begin
Higher := False;
If NextCard.Rank > LastCard.Rank
Then Higher := True;
IsNextCardHigher := Higher;
End;
Function GetPlayerName : String;
Var
PlayerName : String;
Begin
Writeln;
Write('Please enter your name: ');
Readln(PlayerName);
Writeln;
GetPlayerName := PlayerName;
End;
Function GetChoiceFromUser : Char;
Var
Choice : Char;
Begin
Write('Do you think the next card will be higher than the last card (enter y or n)? ');
Readln(Choice);
GetChoiceFromUser := Choice;
End;
Procedure DisplayEndOfGameMessage(Score : Integer);
Begin
Writeln;
Writeln('GAME OVER!');
Writeln('Your score was ', Score);
If Score = 51
Then Writeln('WOW! You completed a perfect game.');
Writeln;
End;
Procedure DisplayCorrectGuessMessage(Score : Integer);
Begin
Writeln;
Writeln('Well done! You guessed correctly.');
Writeln('Your score is now ', Score, '.');
Writeln;
End;
Procedure ResetRecentScores(Var RecentScores : TRecentScores);
Var
Count : Integer;
Begin
For Count := 1 To NoOfRecentScores
Do
Begin
RecentScores[Count].Name := '';
RecentScores[Count].Score := 0;
End;
End;
Procedure DisplayRecentScores(RecentScores : TRecentScores);
Var
Count : Integer;
Begin
Writeln;
Writeln('Recent scores:');
Writeln;
For Count := 1 To NoOfRecentScores
Do Writeln(RecentScores[Count].Name, ' got a score of ', RecentScores[Count].Score);
Writeln;
Writeln('Press the Enter key to return to the main menu');
Writeln;
Readln;
End;
Procedure UpdateRecentScores(Var RecentScores : TRecentScores; Score : Integer);
Var
PlayerName : String;
Count : Integer;
FoundSpace : Boolean;
Begin
PlayerName := GetPlayerName;
FoundSpace := False;
Count := 1;
While Not FoundSpace And (Count <= NoOfRecentScores)
Do If RecentScores[Count].Name = ''
Then FoundSpace := True
Else Count := Count + 1;
If Not FoundSpace
Then
Begin
For Count := 1 To NoOfRecentScores - 1
Do RecentScores[Count] := RecentScores[Count + 1];
Count := NoOfRecentScores;
End;
RecentScores[Count].Name := PlayerName;
RecentScores[Count].Score := Score;
End;
Procedure PlayGame(Deck : TDeck; Var RecentScores : TRecentScores);
Var
NoOfCardsTurnedOver : Integer;
GameOver : Boolean;
LastCard : TCard;
NextCard : TCard;
Higher : Boolean;
Choice : Char;
Begin
GameOver := False;
GetCard(LastCard, Deck, 0);
DisplayCard(LastCard);
NoOfCardsTurnedOver := 1;
While (NoOfCardsTurnedOver < 52) And Not GameOver
Do
Begin
GetCard(NextCard, Deck, NoOfCardsTurnedOver);
Repeat
Choice := GetChoiceFromUser;
Until (Choice = 'y') Or (Choice = 'n');
DisplayCard(NextCard);
NoOfCardsTurnedOver := NoOfCardsTurnedOver + 1;
Higher := IsNextCardHigher(LastCard, NextCard);
If Higher And (Choice = 'y') Or Not Higher And (Choice = 'n')
Then
Begin
DisplayCorrectGuessMessage(NoOfCardsTurnedOver - 1);
LastCard := NextCard;
End
Else GameOver := True;
End;
If GameOver
Then
Begin
DisplayEndOfGameMessage(NoOfCardsTurnedOver - 2);
UpdateRecentScores(RecentScores, NoOfCardsTurnedOver - 2);
End
Else
Begin
DisplayEndOfGameMessage(51);
UpdateRecentScores(RecentScores, 51);
End;
End;
Begin
Randomize;
Repeat
DisplayMenu;
Choice := GetMenuChoice;
Case Choice Of
'1':
Begin
LoadDeck(Deck);
ShuffleDeck(Deck);
PlayGame(Deck, RecentScores);
End;
'2':
Begin
LoadDeck(Deck);
PlayGame(Deck, RecentScores);
End;
'3': DisplayRecentScores(RecentScores);
'4': ResetRecentScores(RecentScores);
End;
Until Choice = 'q';
End.