A-level Computing 2009/AQA/Problem Solving, Programming, Data Representation and Practical Exercise/Skeleton code/2014 Exam/Section D

Potential Questions

edit

At 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.

edit

VB.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

edit

VB.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

edit

VB.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

edit

VB.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

edit

VB.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

edit

VB.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
—Geoguy180--

Python Solution

Answer:


  1. 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.

edit

VB.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.

edit

VB.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

edit

VB.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.

edit

Second 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 shown)
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!)

edit

VB.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

edit

VB.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

edit

VB.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.

edit

As 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.

edit

VB.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.

edit

VB.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

edit

VB.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 varible 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.

edit

Basically 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*/

edit

VB.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

edit

VB.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

edit

Code provided by AQA is linked here

edit

VB.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.