A-level Computing/AQA/Paper 1/Skeleton program/2024

From Wikibooks, open books for an open world
Jump to navigation Jump to search

This is for the AQA A Level Computer Science Specification.

This is where suggestions can be made about what some of the questions might be and how we can solve them.

Please be respectful and do not vandalise the page, as this would affect students' preparation for exams!

Please do not discuss questions on this page. Instead use the discussion page.

Section C Predictions[edit | edit source]

The 2024 paper 1 will contain 3 questions worth 11 marks in total (one 3 marker one 2 marker and one 6 marker). As long as you know the program well, this will be a walk in the park.

Section D Predictions[edit | edit source]

Programming Questions on Skeleton Program

  • The 2024 paper 1 contains 4 questions: a 5 mark, a 6 mark question and two 14 mark questions - these marks include the screen capture, so the likely marks for the coding will be 1-2 marks lower.
  • The 2023 paper 1 contains 4 questions: a 5 mark, a 9 mark question, a 10 mark question and one 13 mark question - these marks include the screen capture(s), so the likely marks for the coding will be 1-2 marks lower.
  • The 2022 paper 1 contained 4 questions: a 5 mark, a 9 mark question, a 11 mark question and one 13 mark question - these marks include the screen capture(s), so the likely marks for the coding will be 1-2 marks lower.
  • The 2021 paper 1 contained 4 questions: a 6 mark, an 8 mark question, a 9 mark question and one 14 mark question - these marks include the screen capture(s), so the likely marks for the coding will be 1-2 marks lower.
  • The 2020 paper 1 contained 4 questions: a 6 mark, an 8 mark question, a 11 mark question and one 12 mark question - these marks include the screen capture(s), so the likely marks for the coding will be 1-2 marks lower.
  • The 2019 paper 1 contained 4 questions: a 5 mark, an 8 mark question, a 9 mark question and one 13 mark question - these marks include the screen capture(s), so the marks for the coding will be 1-2 marks lower.
  • The 2018 paper 1 contained 5 questions: a 2 mark question, a 5 mark question, two 9 mark questions, and one 12 mark question - these marks include the screen capture(s).
  • The 2017 paper 1 contained 5 questions: a 5 mark question, three 6 mark questions, and one 12 mark question.

Current questions are speculation by contributors to this page.

Question 1 - Symbol Case[edit | edit source]

Lower case symbols are not accepted. E.g. if you enter 'q' it is not recognised as 'Q'. Fix this.

C#:

Easy solution just add .ToUpper() and it will change your lowercase inputs to uppercase and allow them to work.}}

private string GetSymbolFromUser()
{
     string Symbol = "";
     while (!AllowedSymbols.Contains(Symbol))
     {
          Console.Write("Enter symbol: ");
          Symbol = Console.ReadLine().ToUpper();
      }
      return Symbol;
}


Delphi/Pascal:


Java:

    private String getSymbolFromUser() {
        String symbol = "";
        while (!allowedSymbols.contains(symbol)) {
            Console.write("Enter symbol: ");
            symbol = Console.readLine();
            symbol = symbol.toUpperCase(); //added line
        }
        return symbol;
    }


Python:

    def __GetSymbolFromUser(self):
        Symbol = ""
        while not Symbol in self.__AllowedSymbols:
            Symbol = input("Enter symbol: ").upper()
        return Symbol


VB.NET:

A simple solution, just add UCase to change all input to upper case.

  Private Function GetSymbolFromUser() As String
            Dim Symbol As String = ""
            While Not AllowedSymbols.Contains(Symbol)
                Console.Write("Enter symbol: ")
                Symbol = UCase(Console.ReadLine())
            End While
            Return Symbol
        End Function


Question 2 - Game file not existing[edit | edit source]

If a filename is entered that does not exist, the game is unplayable (infinite loop). Amend the program so that in this case the default game is played, with a suitable message to indicate this.

C#:

static void Main(string[] args)
{
    string Again = "y";
    int Score;
    while (Again == "y")
    {
        Console.Write("Press Enter to start a standard puzzle or enter name of file to load: ");
        string Filename = Console.ReadLine();
        Puzzle MyPuzzle;
        if (Filename.Length > 0)
        {
            // new code for question 2 - use try/catch in main and otherwise cause default game to be played

            try
            {
                MyPuzzle = new Puzzle(Filename + ".txt");
            }
            catch
            {
                Console.WriteLine("Invalid file. Playing default puzzle instead.");
                MyPuzzle = new Puzzle(8, Convert.ToInt32(8 * 8 * 0.6));
            }
            // end of new code for question 2
        }
        else
        {
            MyPuzzle = new Puzzle(8, Convert.ToInt32(8 * 8 * 0.6));
        }
        Score = MyPuzzle.AttemptPuzzle();
        Console.WriteLine("Puzzle finished. Your score was: " + Score);
        Console.Write("Do another puzzle? ");
        Again = Console.ReadLine().ToLower();
    }
    Console.ReadLine();
}

// try/catch removed from loadPuzzle subroutine
private void LoadPuzzle(string Filename)
{

    using (StreamReader MyStream = new StreamReader(Filename))
    {
        int NoOfSymbols = Convert.ToInt32(MyStream.ReadLine());
        for (var Count = 1; Count <= NoOfSymbols; Count++)
        {
            AllowedSymbols.Add(MyStream.ReadLine());
        }
        int NoOfPatterns = Convert.ToInt32(MyStream.ReadLine());
        for (var Count = 1; Count <= NoOfPatterns; Count++)
        {
            List<string> Items = MyStream.ReadLine().Split(',').ToList();
            Pattern P = new Pattern(Items[0], Items[1]);
            AllowedPatterns.Add(P);
        }
        GridSize = Convert.ToInt32(MyStream.ReadLine());
        for (var Count = 1; Count <= GridSize * GridSize; Count++)
        {
            Cell C;
            List<string> Items = MyStream.ReadLine().Split(',').ToList();
            if (Items[0] == "@")
            {
                C = new BlockedCell();
            }
            else
            {
                C = new Cell();
                C.ChangeSymbolInCell(Items[0]);
                for (var CurrentSymbol = 1; CurrentSymbol < Items.Count; CurrentSymbol++)
                {
                    C.AddToNotAllowedSymbols(Items[CurrentSymbol]);
                }
            }
            Grid.Add(C);
        }
        Score = Convert.ToInt32(MyStream.ReadLine());
        SymbolsLeft = Convert.ToInt32(MyStream.ReadLine());
    }
}
}}


Delphi/Pascal:


Java:

//Change loadfile to return a boolean to say if it was successful

    private boolean loadPuzzle(String filename) {
        boolean success = true;
        try {
            File myStream = new File(filename);
            Scanner scan = new Scanner(myStream);
            int noOfSymbols = Integer.parseInt(scan.nextLine());
            for (int count = 0; count < noOfSymbols; count++) {
                allowedSymbols.add(scan.nextLine());
            }
            int noOfPatterns = Integer.parseInt(scan.nextLine());
            for (int count = 0; count < noOfPatterns; count++) {
                String[] items = scan.nextLine().split(",", 2);
                Pattern p = new Pattern(items[0], items[1]);
                allowedPatterns.add(p);
            }
            gridSize = Integer.parseInt(scan.nextLine());
            for (int count = 1; count <= gridSize * gridSize; count++) {
                Cell c;
                String[] items = scan.nextLine().split(",", 2);
                if (items[0].equals("@")) {
                    c = new BlockedCell();
                } else {
                    c = new Cell();
                    c.changeSymbolInCell(items[0]);
                    for (int currentSymbol = 1; currentSymbol < items.length; currentSymbol++) {
                        c.addToNotAllowedSymbols(items[currentSymbol]);
                    }
                }
                grid.add(c);
            }
            score = Integer.parseInt(scan.nextLine());
            symbolsLeft = Integer.parseInt(scan.nextLine());
        } catch (Exception e) {
            Console.writeLine("Puzzle not loaded");
            success = false;
        }
        return success;
    }

//Change the Puzzle(filename) constructor to load a default 8*8 puzzle if the filename is invalid

    public Puzzle(String filename) {
        grid = new ArrayList<>();
        allowedPatterns = new ArrayList<>();
        allowedSymbols = new ArrayList<>();
        if (!loadPuzzle(filename)) {
            //the puzzle could not be loaded - run normal game with default size and symbols
            score = 0;
            symbolsLeft = (int) (8*8*0.6);
            gridSize = 8;
            grid = new ArrayList<>();
            for (int count = 1; count < gridSize * gridSize + 1; count++) {
                Cell c;
                if (getRandomInt(1, 101) < 90) {
                    c = new Cell();
                } else {
                    c = new BlockedCell();
                }
                grid.add(c);
            }
            allowedPatterns = new ArrayList<>();
            allowedSymbols = new ArrayList<>();
            Pattern qPattern = new Pattern("Q", "QQ**Q**QQ");
            allowedPatterns.add(qPattern);
            allowedSymbols.add("Q");
            Pattern xPattern = new Pattern("X", "X*X*X*X*X");
            allowedPatterns.add(xPattern);
            allowedSymbols.add("X");
            Pattern tPattern = new Pattern("T", "TTT**T**T");
            allowedPatterns.add(tPattern);
            allowedSymbols.add("T");
        }
    }


Python:

This function edits the __LoadPuzzle function so that it loops back to Main() if it fails to load the game (i.e. the file name was invalid) which results in the user being prompted to re-enter the filename.

#the DefaultGame function is to be created in the main procedure
def DefaultGame():
    Again = "y"
    Score = 0
    while Again == "y":
        MyPuzzle = Puzzle(8, int(8 * 8 * 0.6))
        Score = MyPuzzle.AttemptPuzzle()
        print("Puzzle finished. Your score was: " + str(Score))
        Again = input("Do another puzzle? ").lower()

#this is in the puzzle class
def __LoadPuzzle(self, Filename):
        try:
            with open(Filename) as f:
                NoOfSymbols = int(f.readline().rstrip())
                for Count in range (1, NoOfSymbols + 1):
                    self.__AllowedSymbols.append(f.readline().rstrip())
                NoOfPatterns = int(f.readline().rstrip())
                for Count in range(1, NoOfPatterns + 1):
                    Items = f.readline().rstrip().split(",")
                    P = Pattern(Items[0], Items[1])
                    self.__AllowedPatterns.append(P)
                self.__GridSize = int(f.readline().rstrip())
                for Count in range (1, self.__GridSize * self.__GridSize + 1):
                    Items = f.readline().rstrip().split(",")
                    if Items[0] == "@":
                        C = BlockedCell()
                        self.__Grid.append(C)
                    else:
                        C = Cell()
                        C.ChangeSymbolInCell(Items[0])
                        for CurrentSymbol in range(1, len(Items)):
                            C.AddToNotAllowedSymbols(Items[CurrentSymbol])
                        self.__Grid.append(C)
                self.__Score = int(f.readline().rstrip())
                self.__SymbolsLeft = int(f.readline().rstrip())
        except:
            print("Filename not valid, re-enter on next line")
            #This creates a Default puzzle, instead of asking for a new Filename
            DefaultGame()


VB.NET:

This helps to reset the code so that the program isn't stuck in an infinite loop trying to collect information that cannot be used. Allows the user another chance to re-enter the file name for the puzzle.

        Private Sub LoadPuzzle(Filename As String)
            Try
                Using MyStream As New StreamReader(Filename)
                    Dim NoOfSymbols As Integer = MyStream.ReadLine()
                    For Count = 1 To NoOfSymbols
                        AllowedSymbols.Add(MyStream.ReadLine())
                    Next
                    Dim NoOfPatterns As Integer = MyStream.ReadLine()
                    For Count = 1 To NoOfPatterns
                        Dim Items As List(Of String) = MyStream.ReadLine().Split(",").ToList()
                        Dim P As Pattern = New Pattern(Items(0), Items(1))
                        AllowedPatterns.Add(P)
                    Next
                    GridSize = Convert.ToInt32(MyStream.ReadLine())
                    For Count = 1 To GridSize * GridSize
                        Dim C As Cell
                        Dim Items As List(Of String) = MyStream.ReadLine().Split(",").ToList()
                        If Items(0) = "@" Then
                            C = New BlockedCell()
                        Else
                            C = New Cell()
                            C.ChangeSymbolInCell(Items(0))
                            For CurrentSymbol = 1 To Items.Count - 1
                                C.AddToNotAllowedSymbols(Items(CurrentSymbol))
                            Next
                        End If
                        Grid.Add(C)
                    Next
                    Score = MyStream.ReadLine()
                    SymbolsLeft = MyStream.ReadLine()
                End Using
            Catch
                Console.WriteLine("Puzzle not loaded")
                Call Main() 
            End Try
        End Sub


Question 3 - Blow up a block (blocked cell)[edit | edit source]

Have a 'bomb' that can remove or 'blow-up' a block in a 'blocked cell', but costs you some of your score (minus some points):

C#:

// start change
private string GetSymbolFromUser()
{
    string Symbol = "";
    while (!AllowedSymbols.Contains(Symbol) && Symbol != "bomb")
    {
        Console.Write("Enter symbol or 'bomb' to blow up an @: ");
        Symbol = Console.ReadLine();
    }
    return Symbol;
}
// end change

public virtual int AttemptPuzzle()

// start change
string Symbol = GetSymbolFromUser();
if (Symbol == "bomb" && Score >= 10)
{
    int i = (GridSize - Row) * GridSize + Column  1;
    Grid[i] = new Cell(CurrentCell.GetSymbolsNotAllowed);
    Score -= 10;
}
else if (Symbol == "bomb" && Score < 10)
{
    Console.WriteLine("You do not have sufficient score to use this move");
}
// end change

else
{
    SymbolsLeft -= 1;
    Cell CurrentCell = GetCell(Row, Column);
    if (CurrentCell.CheckSymbolAllowed(Symbol))
    {
        CurrentCell.ChangeSymbolInCell(Symbol);
        int AmountToAddToScore = CheckForMatchWithPattern(Row, Column);
        if (AmountToAddToScore > 0)
        {
            Score += AmountToAddToScore;
        }
    }
    if (SymbolsLeft == 0)
    {
        Finished = true;
    }
}
// end change
// start change (in class Cell)
public Cell(List<string> _symbolsNotAllowed)
{
    Symbol = "";
    SymbolsNotAllowed = _symbolsNotAllowed;
}

public List<string> GetSymbolsNotAllowed
{
    get { return SymbolsNotAllowed; }
}
// end change


Delphi/Pascal:


Java:


Python:

This adds a new symbol "B" which can only be played on a blocked tile.

# Add to the init of Puzzle
self.__AllowedSymbols.append("B")

def AttemptPuzzle(self):
    Finished = False
    while not Finished:
        self.DisplayPuzzle()
        print("Current score: " + str(self.__Score))
        Row = -1
        Valid = False
        while not Valid:
            try:
                Row = int(input("Enter row number: "))
                Valid = True
            except:
                pass
        Column = -1
        Valid = False
        while not Valid:
            try:
                Column = int(input("Enter column number: "))
                Valid = True
            except:
                pass
        Symbol = self.__GetSymbolFromUser()
        self.__SymbolsLeft -= 1
        CurrentCell = self.__GetCell(Row, Column)

        # CHANGES HERE
        if Symbol == "B" and type(CurrentCell) == BlockedCell:
            Index = (self.__GridSize - Row) * self.__GridSize + Column - 1
            self.__Grid[Index] = Cell()  # Change Blocked Cell to regular Cell so the cell is "open"
            self.__Score -= 3

        elif CurrentCell.CheckSymbolAllowed(Symbol) and Symbol != "B":
            CurrentCell.ChangeSymbolInCell(Symbol)
            AmountToAddToScore = self.CheckforMatchWithPattern(Row, Column)
            if AmountToAddToScore > 0:
                self.__Score += AmountToAddToScore

        if self.__SymbolsLeft == 0:
            Finished = True
    print()
    self.DisplayPuzzle()
    print()
    return self.__Score


VB.NET:

      ‘’in Function AttemptPuzzle()            
     '' start change
                Dim Symbol As String = GetSymbolFromUser()
                Dim CurrentCell As Cell = GetCell(Row, Column)
                If ((Symbol = "bomb") And (Score >= 10)) Then
                    Dim i As Integer = ((GridSize - Row) * GridSize + Column) - 1
                    Grid(i) = New Cell
                    Score -= 10
                ElseIf ((Symbol = "bomb") And (Score < 10)) Then
                    Console.WriteLine("You do not have suffiecient score to use this move")

                Else
                    SymbolsLeft -= 1

                    If CurrentCell.CheckSymbolAllowed(Symbol) Then
                        CurrentCell.ChangeSymbolInCell(Symbol)
                        Dim AmountToAddToScore As Integer = CheckForMatchWithPattern(Row, Column)
                        If AmountToAddToScore > 0 Then
                            Score += AmountToAddToScore
                        End If
                    End If
                    If SymbolsLeft = 0 Then
                        Finished = True
                    End If
                End If
                ''end change

Private Function GetSymbolFromUser() As String

    Dim Symbol As String = ""
    ''start change
    While ((Not AllowedSymbols.Contains(Symbol)) And (Not Symbol = "bomb"))
        '' end change
        Console.Write("Enter symbol or 'bomb' to blow up an @: ")
        Symbol = (Console.ReadLine())
    End While

    Return Symbol
End Function


Question 4 - Add additional symbols/letters[edit | edit source]

Add additional letters/symbols e.g. L or O or U or V or C or H or I.

C#:

The code here will allow you to get 10 points for creating an L shape in the grid.
Pattern LPattern = new Pattern("L", "L***LLLL*");
AllowedPatterns.Add(LPattern);
AllowedSymbols.Add("L");


Delphi/Pascal:


Java:


Python:

The way that the pattern checking works is in clockwise. This is the order

1 2 3
8 9 4
7 6 5

so the pattern for Q is QQ**Q**QQ, and if you place the symbols in that order, you get the correct pattern.

# Edit Puzzle().init()
class Puzzle():
    def __init__(self, *args):
        LPattern = Pattern("L", "L***LLLL*")
        self.__AllowedPatterns.append(LPattern)
        self.__AllowedSymbols.append("L")


VB.NET:

This allows the user to create an L pattern that results in them earning 10 points.

           Dim LPattern As Pattern = New Pattern("L", "L***LLLL*")
           AllowedPatterns.Add(LPattern)
           AllowedSymbols.Add("L")


Question 5 - Save current game (status)[edit | edit source]

Save the current status of the game (file-handling)/writing to a text file.

C#:

public virtual int AttemptPuzzle()
{
    bool Finished = false;
    while (!Finished)
    {
        DisplayPuzzle();
        Console.WriteLine("Current score: " + Score);
        bool Valid = false;
        int Row = -1;
        while (!Valid)
        {
            Console.Write("Enter row number: ");
            try
            {
                Row = Convert.ToInt32(Console.ReadLine());
                Valid = true;
            }
            catch
            {
            }
        }
        int Column = -1;
        Valid = false;
        while (!Valid)
        {
            Console.Write("Enter column number: ");
            try
            {
                Column = Convert.ToInt32(Console.ReadLine());
                Valid = true;
            }
            catch
            {
            }
        }
        string Symbol = GetSymbolFromUser();
        SymbolsLeft -= 1
        Cell CurrentCell = GetCell(Row, Column);
        if (CurrentCell.CheckSymbolAllowed(Symbol))
        {
            SymbolsLeft -= 1;
            CurrentCell.ChangeSymbolInCell(Symbol);
            int AmountToAddToScore = CheckForMatchWithPattern(Row, Column);
            if (AmountToAddToScore > 0)
            {
                Score += AmountToAddToScore;
            }
        }
        if (SymbolsLeft == 0)
        {
            Finished = true;
        }
        //New code for question 5 including calling new SavePuzzle() method:
        Console.WriteLine("Do you wish to save your puzzle and exit? (Y for yes)");
        if (Console.ReadLine().ToUpper() == "Y")
        {
            Console.WriteLine("What would you like to save your puzzle as?");
            string file = Console.ReadLine();
            SavePuzzle(file);
            Console.WriteLine("Puzzle Successfully Saved.");
            break;
        }
        //end of code for question 5
    }
    Console.WriteLine();
    DisplayPuzzle();
    Console.WriteLine();
    return Score;

//new SavePuzzle() method:
private void SavePuzzle(string filename)
{
    filename = filename + ".txt";
    using (StreamWriter sw = new StreamWriter(filename))
    {
        sw.WriteLine(AllowedSymbols.Count);
        foreach (var symbol in AllowedSymbols)
        {
            sw.WriteLine(symbol);
        }
        sw.WriteLine(AllowedPatterns.Count);
        foreach (var pattern in AllowedPatterns)
        {
            sw.WriteLine(pattern.GetPatternSymbol() + "," + pattern.GetPatternSequence());
        }
        sw.WriteLine(GridSize);

        foreach (Cell C in Grid)
        {
            List<string> notAllowedSymbol = C.returnNotAllowedSymbols();
            try
            {
                sw.WriteLine(C.GetSymbol() + "," + notAllowedSymbol[0]);
            }
            catch
            {
                sw.WriteLine(C.GetSymbol() + ",");
            }
        }
        sw.WriteLine(Score);
        sw.WriteLine(SymbolsLeft);
    }
}

// new returnNotAllowedSymbol() method in Pattern class 
public virtual List<string> returnNotAllowedSymbols()
{
    return SymbolsNotAllowed;
}


Delphi/Pascal:


Java:

}

   private void savePuzzle(String filename){
       try {
           FileWriter myWriter = new FileWriter(filename);
           myWriter.write(""+allowedSymbols.size()+"\n");
           for (String s:allowedSymbols){
               myWriter.write(s+"\n");
           }
           myWriter.write(""+allowedPatterns.size()+"\n");
           for (Pattern p:allowedPatterns){
               myWriter.write(p.getPatternSequence().charAt(0)+","+p.getPatternSequence()+"\n");
           }
           myWriter.write(""+gridSize+"\n");
           for (Cell c:grid){
             String toWrite=""+c.getSymbol()+",";
             for(String s:allowedSymbols){
                 if (!c.checkSymbolAllowed(s)){
                     toWrite=toWrite+s;
                 }
             }              
             myWriter.write(toWrite+"\n");
           }
           myWriter.write(score+"\n");
           myWriter.write(symbolsLeft+"\n");
           myWriter.close();
       } catch (Exception e) {
           Console.writeLine("Puzzle not saved");
       }
   }
// And changes in attemptPuzzle

           Console.writeLine("Do you wish to save and quit the game y/n?: ");
           String quit = Console.readLine();
           if (quit.equals("y")){
               Console.writeLine("Please enter a filename with a .txt extension: ");
               String fname=Console.readLine();
               savePuzzle(fname);
               finished = true;
           }


Python:

Some of the get methods have to be added manually in each class.

class Puzzle:
    def __save_puzzle(self, filename):
        with open(filename, 'w') as f:
            f.write(f"{len(self.__AllowedSymbols)}\n")
            for i in self.__AllowedSymbols:
                f.write(f"{i}\n")
            f.write(f"{len(self.__AllowedPatterns)}\n")
            for i in self.__AllowedPatterns:
                f.write(f"{i.GetSymbol()},{i.GetPatternSequence()}\n")
            f.write(f"{self.__GridSize}\n")
            for cell in self.__Grid:
                symbol = cell.GetSymbol()
                f.write(f"{symbol if symbol != '-' else ''},{','.join(cell.GetNotAllowedSymbols())}\n")

            f.write(f"{self.__Score}\n")
            f.write(f"{self.__SymbolsLeft}\n")


VB.NET:

Sub SaveGame()

           Console.WriteLine("Enter filename")
           Dim filename As String = Console.ReadLine
           filename = filename & ".txt"
           Dim SR As New StreamWriter(filename)
           'this is the number of symbols
           SR.WriteLine(AllowedSymbols.Count)
           'this loops through the different symbols
           For i As Integer = 0 To AllowedSymbols.Count - 1
               SR.WriteLine(AllowedSymbols(i))
           Next
           'this is the number of patterns
           SR.WriteLine(AllowedPatterns.Count)
           'displays the different patterns
           For j As Integer = 0 To AllowedPatterns.Count - 1
               SR.WriteLine(AllowedSymbols(j) & "," & AllowedPatterns(j).GetPatternSequence)
           Next
           'this is the gridsize
           SR.WriteLine(GridSize)
           'this writes out the grid
           For a As Integer = 0 To Grid.Count - 1
               SR.WriteLine(Grid(a).GetSymbol() & Grid(a).returnNotAllowedList)
           Next
           'this is the current score
           SR.WriteLine(Score)
           'this is the number of symbols left
           SR.WriteLine(SymbolsLeft)
           SR.Close()
End Sub


Question 6 - Rotated letter/symbol[edit | edit source]

Score a 'rotated' symbol/letter (lower score?)

C#:

Rotated letters are given 5 points rather than 10.

 public virtual int CheckForMatchWithPattern(int Row, int Column)
 {
     for (var StartRow = Row + 2; StartRow >= Row; StartRow--)
     {
         for (var StartColumn = Column - 2; StartColumn <= Column; StartColumn++)
         {
             try
             {
                 string PatternString = "";
                 PatternString += GetCell(StartRow, StartColumn).GetSymbol();
                 PatternString += GetCell(StartRow, StartColumn + 1).GetSymbol();
                 PatternString += GetCell(StartRow, StartColumn + 2).GetSymbol();
                 PatternString += GetCell(StartRow - 1, StartColumn + 2).GetSymbol();
                 PatternString += GetCell(StartRow - 2, StartColumn + 2).GetSymbol();
                 PatternString += GetCell(StartRow - 2, StartColumn + 1).GetSymbol();
                 PatternString += GetCell(StartRow - 2, StartColumn).GetSymbol();
                 PatternString += GetCell(StartRow - 1, StartColumn).GetSymbol();
                 PatternString += GetCell(StartRow - 1, StartColumn + 1).GetSymbol();

                 for (int i = 0; i < 4; i++)
                 {
                     foreach (var P in AllowedPatterns)
                     {
                         string CurrentSymbol = GetCell(Row, Column).GetSymbol();
                         if (P.MatchesPattern(PatternString, CurrentSymbol))
                         {
                             GetCell(StartRow, StartColumn).AddToNotAllowedSymbols(CurrentSymbol);
                             GetCell(StartRow, StartColumn + 1).AddToNotAllowedSymbols(CurrentSymbol);
                             GetCell(StartRow, StartColumn + 2).AddToNotAllowedSymbols(CurrentSymbol);
                             GetCell(StartRow - 1, StartColumn + 2).AddToNotAllowedSymbols(CurrentSymbol);
                             GetCell(StartRow - 2, StartColumn + 2).AddToNotAllowedSymbols(CurrentSymbol);
                             GetCell(StartRow - 2, StartColumn + 1).AddToNotAllowedSymbols(CurrentSymbol);
                             GetCell(StartRow - 2, StartColumn).AddToNotAllowedSymbols(CurrentSymbol);
                             GetCell(StartRow - 1, StartColumn).AddToNotAllowedSymbols(CurrentSymbol);
                             GetCell(StartRow - 1, StartColumn + 1).AddToNotAllowedSymbols(CurrentSymbol);
                             
                             if (i == 0)
                             {
                                 return 10;
                             }
                             else
                             {
                                 return 5;
                             }
                         }
                     }

                     PatternString = PatternString.Substring(2, 6) + PatternString.Substring(0, 2) + PatternString[8];
                 }
             }
             catch
             {
             }
         }
     }
     return 0;
 }


Delphi/Pascal:


Java:

public int CheckforMatchWithPattern(int Row, int Column) {
    for (int StartRow = Row + 2; StartRow > Row - 1; StartRow--) {
        for (int StartColumn = Column - 2; StartColumn < Column + 1; StartColumn++) {
            try {
                String PatternString = "";
                PatternString += this.__GetCell(StartRow, StartColumn).GetSymbol();
                PatternString += this.__GetCell(StartRow, StartColumn + 1).GetSymbol();
                PatternString += this.__GetCell(StartRow, StartColumn + 2).GetSymbol();
                PatternString += this.__GetCell(StartRow - 1, StartColumn + 2).GetSymbol();
                PatternString += this.__GetCell(StartRow - 2, StartColumn + 2).GetSymbol();
                PatternString += this.__GetCell(StartRow - 2, StartColumn + 1).GetSymbol();
                PatternString += this.__GetCell(StartRow - 2, StartColumn).GetSymbol();
                PatternString += this.__GetCell(StartRow - 1, StartColumn).GetSymbol();
                PatternString += this.__GetCell(StartRow - 1, StartColumn + 1).GetSymbol();
                String LeftRotation = PatternString.substring(6, 8) + PatternString.substring(0, 6) + PatternString.substring(8);
                String RightRotation = PatternString.substring(2, 7) + PatternString.substring(0, 2) + PatternString.substring(8);
                String DownRotation = PatternString.substring(4, 8) + PatternString.substring(0, 4) + PatternString.substring(8);
                String[] Rotations = {PatternString, LeftRotation, RightRotation, DownRotation};
                for (Pattern P : this.__AllowedPatterns) {
                    for (String rotation : Rotations) {
                        char CurrentSymbol = this.__GetCell(Row, Column).GetSymbol();
                        if (P.MatchesPattern(rotation, CurrentSymbol)) {
                            this.__GetCell(StartRow, StartColumn).AddToNotAllowedSymbols(CurrentSymbol);
                            this.__GetCell(StartRow, StartColumn + 1).AddToNotAllowedSymbols(CurrentSymbol);
                            this.__GetCell(StartRow, StartColumn + 2).AddToNotAllowedSymbols(CurrentSymbol);
                            this.__GetCell(StartRow - 1, StartColumn + 2).AddToNotAllowedSymbols(CurrentSymbol);
                            this.__GetCell(StartRow - 2, StartColumn + 2).AddToNotAllowedSymbols(CurrentSymbol);
                            this.__GetCell(StartRow - 2, StartColumn + 1).AddToNotAllowedSymbols(CurrentSymbol);
                            this.__GetCell(StartRow - 2, StartColumn).AddToNotAllowedSymbols(CurrentSymbol);
                            this.__GetCell(StartRow - 1, StartColumn).AddToNotAllowedSymbols(CurrentSymbol);
                            this.__GetCell(StartRow - 1, StartColumn + 1).AddToNotAllowedSymbols(CurrentSymbol);
                            return 10;
                        }
                    }
                }
            } catch (Exception e) {
                // Handle exception
            }
        }
    }
    return 0;
}


Python:

    def CheckforMatchWithPattern(self, Row, Column):
        for StartRow in range(Row + 2, Row - 1, -1):
            for StartColumn in range(Column - 2, Column + 1):
                try:
                    PatternString = ""
                    PatternString += self.__GetCell(StartRow, StartColumn).GetSymbol()
                    PatternString += self.__GetCell(StartRow, StartColumn + 1).GetSymbol()
                    PatternString += self.__GetCell(StartRow, StartColumn + 2).GetSymbol()
                    PatternString += self.__GetCell(StartRow - 1, StartColumn + 2).GetSymbol()
                    PatternString += self.__GetCell(StartRow - 2, StartColumn + 2).GetSymbol()
                    PatternString += self.__GetCell(StartRow - 2, StartColumn + 1).GetSymbol()
                    PatternString += self.__GetCell(StartRow - 2, StartColumn).GetSymbol()
                    PatternString += self.__GetCell(StartRow - 1, StartColumn).GetSymbol()
                    PatternString += self.__GetCell(StartRow - 1, StartColumn + 1).GetSymbol()
                    LeftRotation = PatternString[6:8] + PatternString[:6]+PatternString[8]
                    RightRotation = PatternString[2:8] + PatternString[0:2] + PatternString[8]
                    DownRotation = PatternString[4:8] + PatternString[:4] + PatternString[8]
                    Rotations = [PatternString, LeftRotation, RightRotation, DownRotation]
                    for P in self.__AllowedPatterns:
                        for rotation in Rotations:
                            CurrentSymbol = self.__GetCell(Row, Column).GetSymbol()
                            if P.MatchesPattern(rotation, CurrentSymbol):
                                self.__GetCell(StartRow, StartColumn).AddToNotAllowedSymbols(CurrentSymbol)
                                self.__GetCell(StartRow, StartColumn + 1).AddToNotAllowedSymbols(CurrentSymbol)
                                self.__GetCell(StartRow, StartColumn + 2).AddToNotAllowedSymbols(CurrentSymbol)
                                self.__GetCell(StartRow - 1, StartColumn + 2).AddToNotAllowedSymbols(CurrentSymbol)
                                self.__GetCell(StartRow - 2, StartColumn + 2).AddToNotAllowedSymbols(CurrentSymbol)
                                self.__GetCell(StartRow - 2, StartColumn + 1).AddToNotAllowedSymbols(CurrentSymbol)
                                self.__GetCell(StartRow - 2, StartColumn).AddToNotAllowedSymbols(CurrentSymbol)
                                self.__GetCell(StartRow - 1, StartColumn).AddToNotAllowedSymbols(CurrentSymbol)
                                self.__GetCell(StartRow - 1, StartColumn + 1).AddToNotAllowedSymbols(CurrentSymbol)
                                return 10
                except:
                    pass
        return 0


VB.NET:


Question 7 - Game difficulty setting[edit | edit source]

Offer 'game difficulty' setting to change level of game (with greater number of blocked cells = 'more difficult')

C#:

public Puzzle(int Size, int StartSymbols)
{
    Score = 0;
    SymbolsLeft = StartSymbols;
    GridSize = Size;
    Grid = new List<Cell>();

    // new code for question 5

    int notBlockedChance;
    Console.WriteLine("Would you like the difficulty to be easy (E), medium(M), hard(H) or extremely hard (EH)?");
    string difficulty = Console.ReadLine();
    if (difficulty.ToUpper() == "EH")
    {
        notBlockedChance = 50; //these values are just an example and can be modified
    }
    else if (difficulty.ToUpper() == "H")
    {
        notBlockedChance = 60;
    }
    else if (difficulty.ToUpper() == "M")
    {
        notBlockedChance = 75;
    }
    else
    {
        notBlockedChance = 90;
    }

    for (var Count = 1; Count <= GridSize * GridSize; Count++)
    {
        Cell C;


        if (Rng.Next(1, 101) < notBlockedChance)
        //end of new code for question 5
        {
            C = new Cell();
        }
        else
        {
            C = new BlockedCell();
        }
        Grid.Add(C);
    }
    AllowedPatterns = new List<Pattern>();
    AllowedSymbols = new List<string>();
    Pattern QPattern = new Pattern("Q", "QQ**Q**QQ");
    AllowedPatterns.Add(QPattern);
    AllowedSymbols.Add("Q");
    Pattern XPattern = new Pattern("X", "X*X*X*X*X");
    AllowedPatterns.Add(XPattern);
    AllowedSymbols.Add("X");
    Pattern TPattern = new Pattern("T", "TTT**T**T");
    AllowedPatterns.Add(TPattern);
    AllowedSymbols.Add("T");


}


Delphi/Pascal:


Java:

public class PuzzleSP {
    public static void main(String[] args) {
        String again = "y";
        int score;
        while (again.equals("y")) {
            Console.write("Press Enter to start a standard puzzle or enter name of file to load: ");
            String filename = Console.readLine();
            Puzzle myPuzzle;
            if (filename.length() > 0) {
                myPuzzle = new Puzzle(filename + ".txt");
            } else {
            	
            	//start of altered code
            	
            	Console.writeLine("enter a difficulty (1-3 easy to hard): ");
            	int dif = Integer.parseInt(Console.readLine());
            	if(dif < 1 || dif > 3) {
            		dif = 2;
            	}
                myPuzzle = new Puzzle(8, (int)(8 * 8 * 0.6), dif);
                
                //end of altered code
            }
            score = myPuzzle.attemptPuzzle();
            Console.writeLine("Puzzle finished. Your score was: " + score);
            Console.write("Do another puzzle? ");
            again = Console.readLine().toLowerCase();
        }
        Console.readLine();
    }
}


    public Puzzle(int size, int startSymbols, int difficulty) {  //add difficulty setting
        score = 0;
        symbolsLeft = startSymbols;
        gridSize = size;
        grid = new ArrayList<>();
        for (int count = 1; count < gridSize * gridSize + 1; count++) {
            Cell c;
            int num = 0;
            
            //start of altered code
            
            if(difficulty == 1) {
            	num = 90;
            }
            else if(difficulty == 2) {
            	num = 70;
            }
            else if(difficulty == 3) {
            	num = 50;
            }
            
            //the lower num is, the more difficult the game will be.
            
            if (getRandomInt(1, 101) < num) {
                c = new Cell();
            } else {
                c = new BlockedCell();
            }
            grid.add(c);
            
            //end of altered code            
        }


Python:

class Puzzle():
    def __init__(self, *args):
        if len(args) == 1:
            self.__Score = 0
            self.__SymbolsLeft = 0
            self.__GridSize = 0
            self.__Grid = []
            self.__AllowedPatterns = []
            self.__AllowedSymbols = []
            self.__LoadPuzzle(args[0])
        else:
            self.__Score = 0
            self.__SymbolsLeft = args[1]
            self.__GridSize = args[0]
            self.__Grid = []
            print("1: Easy, 2: Normal, 3: Hard")
            difficulty = ""
            while not (difficulty == "1" or difficulty == "2" or difficulty == "3") or not difficulty.isdigit():
                difficulty = input("Enter a difficulty")
            difficulty = int(difficulty)
            difficulties  = {1:95 , 2:80 , 3:65} #modify these values to change difficulties
            for Count in range(1, self.__GridSize * self.__GridSize + 1):
                if random.randrange(1, 101) < difficulties[difficulty]:
                    C = Cell()
                else:
                    C = BlockedCell()
                self.__Grid.append(C)
            self.__AllowedPatterns = []
            self.__AllowedSymbols = []
            QPattern = Pattern("Q", "QQ**Q**QQ")
            self.__AllowedPatterns.append(QPattern)
            self.__AllowedSymbols.append("Q")
            XPattern = Pattern("X", "X*X*X*X*X")
            self.__AllowedPatterns.append(XPattern)
            self.__AllowedSymbols.append("X")
            TPattern = Pattern("T", "TTT**T**T")
            self.__AllowedPatterns.append(TPattern)
            self.__AllowedSymbols.append("T")

## OR
###Adds ability for users to create new puzzle with custom gridsize and Difficulty ###(increase percentile of grid that is blocked, up to 90%)

def Main():
    Again = "y"
    Score = 0
    while Again == "y":
        Filename = input("Press Enter to start a standard puzzle or enter name of file to load: ")
        if len(Filename) > 0:
            MyPuzzle = Puzzle(Filename + ".txt")
        else:
            GrS = 0
            diff = 0
            while GrS < 3 or GrS > 16:
                GrS = int(input("Input Desired Gridsize (i.e. 5 = 5x5 grid)"))
            while diff <= 0 or diff > 9:
                diff = int(input("Input Desired Difficulty 1-9"))
            diff = diff/10
            diff = 1-diff
            MyPuzzle = Puzzle(GrS, int(GrS * GrS * diff))
        Score = MyPuzzle.AttemptPuzzle()
        print("Puzzle finished. Your score was: " + str(Score))
        Again = input("Do another puzzle? ").lower() # add (y/n)


VB.NET:

Difficulty based on number of moves available

Sub Main()

       Dim Again As String = "y"
       Dim Score As Integer
       While Again = "y"
           Console.Write("Press Enter to start a standard puzzle or enter name of file to load: ")
           Dim Filename As String = Console.ReadLine()
           'ADDED CODE - checks that the filename entered has a file existing in the DEBUG folder
           Dim fileExists As Boolean = False
           Dim FullFilename As String = Filename & ".txt"
           If FileIO.FileSystem.FileExists(FullFilename) Then
               fileExists = True
           End If
           'AMENDED CODE - the if statement changed to use the boolean value above instead of
           'using the text length
           Dim MyPuzzle As Puzzle
           If fileExists Then
               MyPuzzle = New Puzzle(Filename & ".txt")
           Else
               'ADDED CODE
               Dim Dif As Integer
               Do
                   Console.WriteLine("Enter a difficulty rating from 1-9")
                   Dif = Console.ReadLine
               Loop Until Dif >= 1 And Dif < 10
               'AMENDED CODE - difficulty rating affects the numbner of moves available
               MyPuzzle = New Puzzle(8, Int(8 * 8 * (1 - (0.1 * Dif))))
           End If


           Score = MyPuzzle.AttemptPuzzle()
           Console.WriteLine("Puzzle finished. Your score was: " & Score)
           Console.Write("Do another puzzle? ")
           Again = Console.ReadLine().ToLower()
       End While
       Console.ReadLine()
   End Sub


Question 8 - Fix symbols placed error[edit | edit source]

When you try place a symbol in a invalid cell it still counts as a placed cell towards the amount of symbols placed.

C#:

public virtual int AttemptPuzzle()
{
    bool Finished = false;
    while (!Finished)
    {
        DisplayPuzzle();
        Console.WriteLine("Current score: " + Score);
        bool Valid = false;
        int Row = -1;
        while (!Valid)
        {
            Console.Write("Enter row number: ");
            try
            {
                Row = Convert.ToInt32(Console.ReadLine());
                Valid = true;
            }
            catch
            {
            }
        }
        int Column = -1;
        Valid = false;
        while (!Valid)
        {
            Console.Write("Enter column number: ");
            try
            {
                Column = Convert.ToInt32(Console.ReadLine());
                Valid = true;
            }
            catch
            {
            }
        }
        string Symbol = GetSymbolFromUser();
        //SymbolsLeft -= 1; => moved inside the IF statement
        Cell CurrentCell = GetCell(Row, Column);
        if (CurrentCell.CheckSymbolAllowed(Symbol))
        {
            SymbolsLeft -= 1; //moved inside if statement to fix error
            CurrentCell.ChangeSymbolInCell(Symbol);
            int AmountToAddToScore = CheckForMatchWithPattern(Row, Column);
            if (AmountToAddToScore > 0)
            {
                Score += AmountToAddToScore;
            }
        }
        if (SymbolsLeft == 0)
        {
            Finished = true;
        }

    }
    Console.WriteLine();
    DisplayPuzzle();
    Console.WriteLine();
    return Score;
}


Delphi/Pascal:


Java:


Python:

    def AttemptPuzzle(self):
        Finished = False
        while not Finished:
            self.DisplayPuzzle()
            print("Current score: " + str(self.__Score))
            Row = -1
            Valid = False
            while not Valid:
                try:
                    Row = int(input("Enter row number: "))
                    Valid = True
                except:
                    pass
            Column = -1
            Valid = False
            while not Valid:
                try:
                    Column = int(input("Enter column number: "))
                    Valid = True
                except:
                    pass
            Symbol = self.__GetSymbolFromUser()
            # self.__SymbolsLeft -= 1 moving this line inside of the if statement
            CurrentCell = self.__GetCell(Row, Column)
            if CurrentCell.CheckSymbolAllowed(Symbol) and CurrentCell.IsEmpty()  == True: # added to make sure that the cell is empty as well before adding to that cell 
                self.__SymbolsLeft -= 1 # moved into the if statement
                CurrentCell.ChangeSymbolInCell(Symbol)
                AmountToAddToScore = self.CheckforMatchWithPattern(Row, Column)
                if AmountToAddToScore > 0:
                    self.__Score += AmountToAddToScore
            if self.__SymbolsLeft == 0:
                Finished = True
        print()
        self.DisplayPuzzle()
        print()
        return self.__Score


VB.NET:


Question 9 - Create a new puzzle file to be imported[edit | edit source]

Create a new puzzle file to be imported into the code for the user to play:

C#:

## annotated puzzle file, so parameters can be altered as needed

4  #number of accepted symbols
Q  
T
X
O  #new symbols can be added here, like so
4  #number of accepted patterns
Q,QQ**Q**QQ
X,X*X*X*X*X
T,TTT**T**T
O,OOOOOOOO*   #new patterns can be added here (in proper format), like so
5  #grid size (if size = x, grid is x by x). number of entries (below) should match grid size (5 * 5 = 25 in this case)
Q,Q   #First symbol is symbol on board, second symbol is symbols not allowed on that grid
Q,Q
@,Q
,
,
Q,Q
Q,Q
,Q  #eg denotes an empty space, but symbol Q is not allowed
,
,
,
X,Q
Q,Q
X,
,
,
,
X,
,
,
,
X,
,
,
,
10  #starting score
1   #number of moves


Delphi/Pascal:


Java:


Python:

## annotated puzzle file, so parameters can be altered as needed

4  #number of accepted symbols
Q  
T
X
O  #new symbols can be added here, like so
4  #number of accepted patterns
Q,QQ**Q**QQ
X,X*X*X*X*X
T,TTT**T**T
O,OOOOOOOO*   #new patterns can be added here (in proper format), like so
5  #grid size (if size = x, grid is x by x). number of entries (below) should match grid size (5 * 5 = 25 in this case)
Q,Q   #First symbol is symbol on board, second symbol is symbols not allowed on that grid
Q,Q
@,Q
,
,
Q,Q
Q,Q
,Q  #eg denotes an empty space, but symbol Q is not allowed
,
,
,
X,Q
Q,Q
X,
,
,
,
X,
,
,
,
X,
,
,
,
10  #starting score
1   #number of moves


VB.NET:


Question 10 - Be able to undo a move[edit | edit source]

Alter the attemptPuzzle subroutine such that the user is asked if they wish to undo their last move prior to the place in the loop where there is a check for symbolsLeft being equal to zero. Warn them that this will lose them 3 points.

If the player chooses to undo:

a.      revert the grid back to its original state

b.      ensure symbolsLeft has the correct value

c.      ensure score reverts to its original value minus the 3 point undo penalty

d. ensure any changes made to a cell’s symbolsNotAllowed list are undone as required

C#:

        while (!Valid)
        {
            Console.Write("Enter column number: ");
            try
            {
                Column = Convert.ToInt32(Console.ReadLine());
                Valid = true;
            }
            catch
            {
            }
        }
        string Symbol = GetSymbolFromUser();
        SymbolsLeft -= 1;

        // change - required in case we need to undo
        int previousScore = Score;

        // this is where the game is updated
        Cell CurrentCell = GetCell(Row, Column);
        if (CurrentCell.CheckSymbolAllowed(Symbol))
        {
            CurrentCell.ChangeSymbolInCell(Symbol);
            int AmountToAddToScore = CheckForMatchWithPattern(Row, Column);
            if (AmountToAddToScore > 0)
            {
                Score += AmountToAddToScore;
            }
        }

        // changed code in AttemptPuzzle here
        DisplayPuzzle();
        Console.WriteLine("Current score: " + Score);

        Console.Write("Do you want to undo (cost 3 points)? y/n: ");
        string answer = Console.ReadLine();

        if (answer == "y" || answer == "Y")
        {
            // undo
            Cell currentCell = GetCell(Row, Column);
            currentCell.RemoveSymbol(Symbol);
            Score = previousScore - 3;
            SymbolsLeft += 1;
        }
        // end change

        if (SymbolsLeft == 0)
        {
            Finished = true;
        }



    }
    Console.WriteLine();
    DisplayPuzzle();
    Console.WriteLine();


    return Score;
}

// added to cell class so that the symbol can be removed if an
// undo is required
public virtual void RemoveSymbol(string SymbolToRemove)
{
    Symbol = "";
    SymbolsNotAllowed.Remove(SymbolToRemove);
}


Delphi/Pascal:


Java:

//Add two atributes in puzzle to store the start position of the last pattern matched
class Puzzle {

    private int score;
    private int symbolsLeft;
    private int gridSize;
    private List<Cell> grid;
    private List<Pattern> allowedPatterns;
    private List<String> allowedSymbols;
    private static Random rng = new Random();

    private int patternStartRow;
    private int patternStartColumn;

// Add a subroutine to the cell class to allow removal from the notAllowedSymbol list

    public void removeLastNotAllowedSymbols() {
        int size = symbolsNotAllowed.size();
        if (size > 0) {
            symbolsNotAllowed.remove(size - 1);
        }
    }

// Alter checkForMatchWithPattern to store the start row and column of any successfully matched pattern
//...

  if (p.matchesPattern(patternString, currentSymbol)) {
           patternStartRow = startRow;
           patternStartColumn = startColumn;
//...etc

//The altered attemptPuzzle subroutine
    public int attemptPuzzle() {
        boolean finished = false;
        while (!finished) {
            displayPuzzle();
            Console.writeLine("Current score: " + score);
            int row = -1;
            boolean valid = false;
            while (!valid) {
                Console.write("Enter row number: ");
                try {
                    row = Integer.parseInt(Console.readLine());
                    valid = true;
                } catch (Exception e) {
                }
            }
            int column = -1;
            valid = false;
            while (!valid) {
                Console.write("Enter column number: ");
                try {
                    column = Integer.parseInt(Console.readLine());
                    valid = true;
                } catch (Exception e) {
                }
            }

            //Set up variables to store the current game state in
            // case of an UNDO
            int undoScore = score;
            int undoSymbolsLeft = symbolsLeft;
            String undoSymbol = getCell(row, column).getSymbol();

            String symbol = getSymbolFromUser();
            symbolsLeft -= 1;
            Cell currentCell = getCell(row, column);
            if (currentCell.checkSymbolAllowed(symbol)) {
                currentCell.changeSymbolInCell(symbol);
                int amountToAddToScore = checkForMatchWithPattern(row, column);
                if (amountToAddToScore > 0) {
                    score += amountToAddToScore;
                }
            }

            //Prompt the user if they wish to undo
            Console.println(" Do you wish to undo your last move? It will cost you 3 points (y/n): ");
            String choice = Console.readLine();
            if (choice.equals("y")) {
                if (score != undoScore) { //A pattern has been matched
                    //The symbolsNotAllowed list may have changed for some cells - the current symbol needs 
                    //                              removing from the end of each list
                    getCell(patternStartRow, patternStartColumn).removeLastNotAllowedSymbols();
                    getCell(patternStartRow, patternStartColumn + 1).removeLastNotAllowedSymbols();
                    getCell(patternStartRow, patternStartColumn + 2).removeLastNotAllowedSymbols();
                    getCell(patternStartRow - 1, patternStartColumn + 2).removeLastNotAllowedSymbols();
                    getCell(patternStartRow - 2, patternStartColumn + 2).removeLastNotAllowedSymbols();
                    getCell(patternStartRow - 2, patternStartColumn + 1).removeLastNotAllowedSymbols();
                    getCell(patternStartRow - 2, patternStartColumn).removeLastNotAllowedSymbols();
                    getCell(patternStartRow - 1, patternStartColumn).removeLastNotAllowedSymbols();
                    getCell(patternStartRow - 1, patternStartColumn + 1).removeLastNotAllowedSymbols();
                }
                score = undoScore - 3;
                symbolsLeft = undoSymbolsLeft;
                currentCell.changeSymbolInCell(undoSymbol);
            }

            if (symbolsLeft == 0) {
                finished = true;
            }
        }
        Console.writeLine();
        displayPuzzle();
        Console.writeLine();
        return score;
    }


Python:

    def AttemptPuzzle(self):
        Finished = False
        while not Finished:
            self.DisplayPuzzle()
            print("Current score: " + str(self.__Score))
            Row = -1
            Valid = False
            while not Valid:
                try:
                    Row = int(input("Enter row number: "))
                    if Row in range(1, self.__GridSize+1):
                        Valid = True
                except:
                    pass
            Column = -1
            Valid = False
            while not Valid:
                try:
                    Column = int(input("Enter column number: "))
                    if Column in range(1, self.__GridSize+1):
                        Valid = True
                except:
                    pass

            # CHANGES START HERE
            Symbol = self.__GetSymbolFromUser()
            undo_symbolsleft = self.__SymbolsLeft
            self.__SymbolsLeft -= 1
            CurrentCell = self.__GetCell(Row, Column)
            undo_cellsymbol = CurrentCell.GetSymbol()
            undo_score = self.__Score
            if CurrentCell.CheckSymbolAllowed(Symbol):
                CurrentCell.ChangeSymbolInCell(Symbol)
                AmountToAddToScore = self.CheckforMatchWithPattern(Row, Column)
                if AmountToAddToScore > 0:
                    self.__Score += AmountToAddToScore

            undo = input('Would you like to undo your move? You will lose 3 points. Y/N: ')
            if undo.upper() == 'Y':
                self.__Score = undo_score - 3
                self.__SymbolsLeft = undo_symbolsleft
                CurrentCell.ChangeSymbolInCell(undo_cellsymbol)
            # CHANGES END HERE

            if self.__SymbolsLeft == 0:
                Finished = True
        print()
        self.DisplayPuzzle()
        print()
        return self.__Score


VB.NET:


Question 11- Validation of Row and Column entries[edit | edit source]

Description of problem: Validate row and column number entries to only allow numbers within the grid size.

C#:

public virtual int AttemptPuzzle()
{
    bool Finished = false;
    while (!Finished)
    {
        DisplayPuzzle();
        Console.WriteLine("Current score: " + Score);
        bool Valid = false;
        int Row = -1;
        while (!Valid)
        {
            Console.Write("Enter row number: ");
            try
            {
                Row = Convert.ToInt32(Console.ReadLine());
                // change to validate row
                if (Row > 0 && Row <= GridSize)
                {
                    Valid = true;
                }
            }
            catch
            {
            }
        }
        int Column = -1;
        Valid = false;
        while (!Valid)
        {
            Console.Write("Enter column number: ");
            try
            {
                Column = Convert.ToInt32(Console.ReadLine());
                // validate column
                if (Column > 0 && Column <= GridSize)
                {
                    Valid = true;
                }

            }
            catch
            {
            }
        }


Delphi/Pascal:


Java:

    public int attemptPuzzle() {
        boolean finished = false;
        while (!finished) {
            displayPuzzle();
            Console.writeLine("Current score: " + score);
            int row = -1;
            boolean valid = false;
            while (!valid) {
                Console.write("Enter row number: ");
                try {
                    row = Integer.parseInt(Console.readLine());
                    if(row>=1&&row<=gridSize){ //new check
                        valid = true; 
                    }
                } catch (Exception e) {
                }
            }
            int column = -1;
            valid = false;
            while (!valid) {
                Console.write("Enter column number: ");
                try {
                    column = Integer.parseInt(Console.readLine());
                    if (column>=1&&column<=gridSize){ //new check
                        valid = true;
                    }
                } catch (Exception e) {
                }
            }
            String symbol = getSymbolFromUser();
            symbolsLeft -= 1;
//etc....


Python:

def AttemptPuzzle(self):
        Finished = False
        while not Finished:
            self.DisplayPuzzle()
            print("Current score: " + str(self.__Score))
            Row = -1
            Valid = False
            while not Valid:
                Row = int(input("Enter row number: "))
                if Row >= 9 or Row <= 0:
                    print("Invalid Row number\nPlease try again\n")
                    continue
                else:
                    Valid = True
            Column = -1
            Valid = False
            while not Valid:
                Column = int(input("Enter column number: "))
                if Column >= 9 or Column <= 0:
                    print("Invalid Column number\nPlease try again\n")
                    continue
                else:
                    Valid = True
            Symbol = self.__GetSymbolFromUser()
            self.__SymbolsLeft -= 1
            CurrentCell = self.__GetCell(Row, Column)
            if CurrentCell.CheckSymbolAllowed(Symbol):
                CurrentCell.ChangeSymbolInCell(Symbol)
                AmountToAddToScore = self.CheckforMatchWithPattern(Row, Column)
                if AmountToAddToScore > 0:
                    self.__Score += AmountToAddToScore
            if self.__SymbolsLeft == 0:
                Finished = True
        print()
        self.DisplayPuzzle()
        print()
        return self.__Score


VB.NET:



Question 12 - Fix the GetCell mapping issue[edit | edit source]

Description of problem: subroutine getCell in the Puzzle class allows for invalid column numbers in some cases, as the algorithm will incorrectly map to a cell that exists in the grid. This should not happen as there could be a time when a pattern matches in checkForMatchWithPattern that doesn't really exist or a cell's 'not-allowed' symbol list will be set wrongly.

C#:

private Cell GetCell(int Row, int Column)
{
    if(Column<1 || Column>GridSize || Row < 1 || Row > GridSize)
    {
        return new BlockedCell();
    }
    else
    {
        return Grid[(GridSize - Row) * GridSize + Column - 1];
    }
}


Delphi/Pascal:


Java:

 private Cell getCell(int row, int column) {
        if (column<1||column>gridSize||row<1||row>gridSize){
            //Force an out of bounds error so the try...catch will work in checkForMatchWithPattern             
            return grid.get(gridSize*gridSize+1);
        }else{            
            return grid.get((gridSize - row) * gridSize + column - 1);
        }
    }


Python:

def __GetCell(self, Row, Column):
     Index = (self.__GridSize - Row) * self.__GridSize + Column - 1
     if self.__GridSize * self.__GridSize > Index >= 0: #Change if statement so that Index cannot be over the max value possible
         return self.__Grid[Index]
     else:
         raise IndexError()


VB.NET:


Question 13 - Why is UpdateCell() empty and never called?[edit | edit source]

Description of problem: Currently, the UpdateCell() method contains 'pass' and is not called anywhere in the program. This will almost certainly be a question, otherwise why would they include it? This may relate to the bombing idea where a Blocked Cell is bombed, and the UpdateCell() is then called to modify this Blocked Cell into a normal cell. Please suggest other ideas of what this method could be used for.


UpdateCell() could be used for unlocking a 3*3 grid if a pattern is broken allowing you to replace the symbol. This would also need to decrease the score after the pattern is broken.

C#:

There are no logical errors with GetCell() as the following extract will prove

public virtual int AttemptPuzzle()
{
    bool Finished = false;
    while (!Finished)
    {
        DisplayPuzzle();

        // row
        for (int row = 8; row >= 1; row--)
        {
            for (int col = 1; col <= 8; col++)
            {
                Cell cell = GetCell(row, col);
                Console.Write(cell.GetSymbol() + " : ");
            }
            Console.Write(Environment.NewLine);
        }
However, if row and column values beyond that of the grid are entered, errors will occur. See solution for Question 12 to solve this issue.


Delphi/Pascal:


Java:


Python:


VB.NET:


Question 14 - Implement a wildcard *[edit | edit source]

Implement a special character * which is a wildcard. The wildcard can be used to represent any character so that multiple matches can be made with the same cell. Give the player 3 wildcards in random positions at the start of the game.

a) Alter the standard Puzzle constructor (not the load game one) to call ChangeSymbolInCell for 3 random cells, passing in * as the new symbol. Note that blocked cells cannot be changed to wildcard ones so you need to add code to ensure the randomly selected cell is not a blocked cell.

b) In class Cell alter the method. ChangeSymbolInCell such that wildcard cells will never have their symbol changed from * once set. In the same class, alter method CheckSymbolAllowed such that wildcard cells always return true.

c) Alter method MatchesPattern in class Pattern to allow correct operation for the new wildcard *

d) Test that a wildcard can successfully match within two different patterns

C#:

class Puzzle
{
    // add property to Puzzle to give 3 wildcards
    private int NumWildcards = 3;


// ensure GetSymbolFromUser will accept wildcard
private string GetSymbolFromUser()
{
    string Symbol = "";
    // take into account the wildcard symbol
    while (!AllowedSymbols.Contains(Symbol) && Symbol != "*" && NumWildcards > 0)
    {
        Console.Write("Enter symbol: ");
        Symbol = Console.ReadLine();
    }

    // only allow three wildcards
    if (Symbol == "*")
    {
        NumWildcards--;
    }

    return Symbol;
}

// modify Matches Pattern
public virtual bool MatchesPattern(string PatternString, string SymbolPlaced)
{
    // ensure that wildcards are taken into account
    if (SymbolPlaced != Symbol && SymbolPlaced != "*")
    {
        return false;
    }
    for (var Count = 0; Count < PatternSequence.Length; Count++)
    {
        // ignore wildcard symbols as these all count
        if (PatternString[Count] == '*')
        {
            continue;
        }

        if (PatternSequence[Count].ToString() == Symbol && PatternString[Count].ToString() != Symbol)
        {
            return false;
        }
    }
    return true;
}


Delphi/Pascal:


Java:

//after the grid is initialised in puzzle:
        int gridLength = grid.size();
        for (int i=0;i<3;i++){
            //Get random cell
            int randcell = getRandomInt(0,gridLength-1);
            if (!grid.get(randcell).getSymbol().equals("@")){
                grid.get(randcell).changeSymbolInCell("*");
            }            
        }

// From Cell class: 
 public void changeSymbolInCell(String newSymbol) {
        if (!symbol.equals("*")){
            symbol = newSymbol;
        }
   }

 public boolean checkSymbolAllowed(String symbolToCheck) {
        if (!symbol.equals("*")){
            for (String item : symbolsNotAllowed) {
                if (item.equals(symbolToCheck)) {
                return false;
                }
            }
        }
        return true;                
    }

   //Pattern class

public boolean matchesPattern(String patternString, String symbolPlaced) {
        Console.println("This pattern sequence: "+patternSequence+ "Passed in PatternString: "+patternString+ "Symbol:"+ symbolPlaced);
        if (!symbolPlaced.equals(symbol)) {
            return false;
        } else {
            for (int count = 0; count < patternSequence.length(); count++) {
                if (patternSequence.charAt(count) == symbol.charAt(0) && patternString.charAt(count) != symbol.charAt(0)) {
                    if (patternString.charAt(count)!='*'){ //only return false if not a wildcard
                        return false;
                    }
                }
            }
        }
        return true;
    }


Python:

Change no. 1:

while self.__wildcards_left > 0:

   SymbolGridCheck = self.__Grid[random.randint(0, len(self.__Grid))]
   if SymbolGridCheck.GetSymbol() != "W":
       SymbolGridCheck.ChangeSymbolInCell("W")
       self.__wildcards_left -= 1

Change no. 2:

def MatchesPattern(self, PatternString, SymbolPlaced):

       if self.__Symbol == "W":
           ...
       elif SymbolPlaced != self.__Symbol:
           return False
       for Count in range(0, len(self.__PatternSequence)):
           try:
               if self.__PatternSequence[Count] == self.__Symbol and PatternString[Count] == "W":
                   ...
               elif self.__PatternSequence[Count] == self.__Symbol and PatternString[Count] != self.__Symbol:
                   return False
           except Exception as ex:
               print(f"EXCEPTION in MatchesPattern: {ex}")
       return True

Change no. 3:

def ChangeSymbolInCell(self, NewSymbol):

       if self._Symbol == "W":
           ...
       else:
           self._Symbol = NewSymbol

def CheckSymbolAllowed(self, SymbolToCheck):

       for Item in self.__SymbolsNotAllowed:
           if Item == "W":
               ...
           elif Item == SymbolToCheck:
               return False
       return True
by Sami Albizreh


VB.NET:


Question 15 - Program allows the user to replace already placed symbols[edit | edit source]

the user can replace already placed symbols, and patterns, and not lose points (can fix either by stopping them replacing, or make them lose the points from the pattern the replaced):

C#:


Delphi/Pascal:


Java:


Python:

    def AttemptPuzzle(self):
        Finished = False
        while not Finished:
            self.DisplayPuzzle()
            print("Current score: " + str(self.__Score))
            Row = -1
            Valid = False
            while not Valid:
                try:
                    Row = int(input("Enter row number: "))
                    Valid = True
                except:
                    pass
            Column = -1
            Valid = False
            while not Valid:
                try:
                    Column = int(input("Enter column number: "))
                    Valid = True
                except:
                    pass
            Symbol = self.__GetSymbolFromUser()
            self.__SymbolsLeft -= 1
            CurrentCell = self.__GetCell(Row, Column)
            if CurrentCell.CheckSymbolAllowed(Symbol) and CurrentCell.GetSymbol() == "-": #And added to check that the cell is empty so that cells cannot be placed on top of each other
                CurrentCell.ChangeSymbolInCell(Symbol)
                AmountToAddToScore = self.CheckforMatchWithPattern(Row, Column)
                if AmountToAddToScore > 0:
                    self.__Score += AmountToAddToScore
            if self.__SymbolsLeft == 0:
                Finished = True
        print()
        self.DisplayPuzzle()
        print()
        return self.__Score


VB.NET:


Question 16 - Program allows the user to create their own patterns and symbols[edit | edit source]

Description of problem:

1) request the user to create their own symbols

2) request the pattern associated with the symbol

3) output an empty grid for the user, so the user can input any coordinates to create their own pattern

4) make sure new symbols and pattern can be verified by the program

EDIT: this would involve changing a text file or creating a new text file - AQA has never told students to do anything text file-based

C#:


Delphi/Pascal:


Java:


Python:


VB.NET:


Question 17- Making a difficulty rating program[edit | edit source]

Description of problem:

1) this program can save each game in record including their score, number of symbols left, time to complete and the original empty grid

2) using these information to make a difficulty rating board, so the user can see their rating and select the one they want to play

C#:


Delphi/Pascal:


Java:


Python:


VB.NET:


Question 18[edit | edit source]

This questions refers to the class Puzzle. A new option of a wildcard is to be added to the game. When the player uses this option, they are given the opportunity to complete a pattern by overriding existing symbols to make that pattern. The wildcard can only be used once in a game.

Task 1:

Add a new option for the user that will appear before each turn. The user should be asked "Do you want to use your wildcard (Y/N)" If the user responds with "Y" then the Row, Column and Symbol will be taken as normal but then the new method ApplyWildcard should be called and the prompt for using the wildcard should no longer be shown in subsequent turns. If the user responds with "N" then the puzzle continues as normal.

Task 2:

Create a new method called ApplyWildcard that will take the Row, Column and Symbol as parameters and do the following:

1. Determine if the pattern can be completed in a 3x3 given the Row, Column and Symbol passed to it.

a) If the pattern can be made the cells in the pattern should be updated using the method UpdateCell() in the Cell class and 5 points added for move.

b) If the pattern cannot be made the user should be given the message "Sorry, the wildcard does not work for this cell – you have no wildcards left"

C#:


Delphi/Pascal:


Java:


Python:


VB.NET: