At the start of a card dressage game $$m \times n$$ cards are put face down on the table ordered in $$m$$ rows of $$n$$ cards. As shown in the figure below, the cards are numbered from left to right and from top to bottom, starting from one.
solutions |
---|
1,3,5,7,9,14 |
1,2,4,5,12,13 |
2,3,5,6,10,15 |
2,7,9,11,13,15 |
1,6,10,11,13,14 |
3,4,11,12,14,15 |
1,2,3,4,6,7,9,10,11,12 |
4,5,6,7,9,10,12,13,14,15 |
The aim of the game is to make sure that all cards are turned face up. Cards can only be reversed according to the following rule: if a card is reversed, all its neighbours must be reversed as well. Neighbours are cards to the left, right, top and bottom — if available — but not diagonally. Upon reversal, a card that was face down is turned face up. Conversely, a card that was face up is turned face down after reversal.
Define a class CardDressage that can be used to play card dressage games. The objects of this class must at least have the following methods:
An initialisation method that takes one or two natural numbers. If two numbers are passed to the method, they respectively represent the number of rows and columns in which the cards are ordered. If only a single number is passed to the method, it represents both the number of rows and columns in which the cards are ordered.
Methods __str__ and __repr__ that both return the same string representation of the object. This string represents a rectangular grid that indicates the position and current top face of the cards. Cards that are face down are represented with a hash symbol (#). Cards that are face up are represented with a dash symbol (-).
A method turnCard that can be used to reverse a particular card according to the rules of the card dressage game. The card number must be passed as an argument to the method. In case the card dressage game has no card with the given number, an AssertionError must be raised with the message invalid card number.
A method turnCards that can be used to reverse a series of cards in a particular order according to the rules of the card dressage game. The numbers of the cards must be passed to the method as a list or tuple of integers. Obviously, the implementation of the method must make use of the method turnCard.
A method won that takes no arguments. This method must return a Boolean value, which indicates whether or not all cards are face up.
>>> game = CardDressage(5, 3)
>>> print(game)
###
###
###
###
###
>>> game.turnCard(1)
>>> game
--#
-##
###
###
###
>>> game.won()
False
>>> game.turnCard(3)
>>> game
-#-
-#-
###
###
###
>>> game.won()
False
>>> game.turnCard(16)
Traceback (most recent call last):
AssertionError: invalid card number
>>> game.turnCard(0)
Traceback (most recent call last):
AssertionError: invalid card number
>>> game.turnCards([5, 7, 9, 14])
>>> game
---
---
---
---
---
>>> game.won()
True
>>> game = CardDressage(5)
>>> game.turnCards([18, 13, 9, 11, 21, 24, 12, 7, 17, 5, 4, 6, 19, 23, 10])
>>> game
-----
-----
-----
-----
-----
>>> game.won()
True
>>> game = CardDressage(3, 6)
>>> game.turnCards((1, 5, 9, 8, 6, 10))
>>> game
-#-###
##-##-
#---##
>>> game.won()
False