This is the practical material for the Intelligent Systems course, based on the card based strategy game Schnapsen.
To get to know the concept of the game, please visit this web page.
Your job is to make a bot that will play this game.
For this implementation of the game, we mostly followed the rules described in the above link, with a few caveats:
- Partial information about the state of the deck is updated automatically, so you don't have to keep track of it yourself.
- In the same vein, it is not the player's responsibility to keep track of their (and their enemy's) points, as it would be in regular Schnapsen. This is done automatically through the game engine, which also removes the aspect of having to declare that you have over 66 points in order to win the game.
- "Closing the talon" is not implemented due to the increased branching factor caused by having to consider the aforementioned closing as an additional possibility.
- Scoring is implemented as the rules would suggest. A player can receive 1-3 points for winning a round, depending on the score differential. However, play.py and tournament.py play the game only in terms of these rounds, not in terms of a "full game" described as playing rounds until one player reaches 7 points.
You require a working Python 2.7 environment and a good text editor or an IDE. You can download Python 2.7 for your machine from the following sources:
You will of course also need a working knowledge of python. If you're looking to brush up on your skills, there are many good tutorials available. For instance:
You do not need to be an expert in python to write a functioning bot. If you already know another programming language, you should be able to get going within a day. You'll pick up the details as the project progresses. However, there are a few things that are important to understand. Check if you know what the following mean. If not, take some time to google them and read up:
What happens if I pass a function a 'State' object, and the function changes the object? Do I keep an unchanged state, or does my state change as well?
What's the difference between a class and an object? How are these expressed in python? What does the self keyword do?
Briefly: a method calling itself. Why would this useful, and how does it work?
Advanced python, but they occur occasionally in the code. Useful to know.
Here are some quick use cases and solutions to help you get a feel for the code.
Let 'state' be the state you're given and let's say you want the size of the stock. Then the following a should do the trick:
size_of stock = state.get_stock_size()
me = state.whose_turn()
cards_hand = state.hand()
for i, card in enumerate(cards_hand):
rank, suit = util.get_card_name(card)
print('Card {} in the hand is {} of {}'.format(i, rank,suit))
NB: The deck of cards is represented through an array. Each index corresponds to a different card, as per the table below.
Aces | 10s | Kings | Queens | Jacks | |
---|---|---|---|---|---|
Clubs | 0 | 1 | 2 | 3 | 4 |
Diamonds | 5 | 6 | 7 | 8 | 9 |
Hearts | 10 | 11 | 12 | 13 | 14 |
Spades | 15 | 16 | 17 | 18 | 19 |
state = State.generate()
# To deterministically generate the same state each time, the generate method can also take a seed, like so:
state = State.generate(25)
# This will always generate the same starting state, to make testing/debugging your bots easier.
print state
me = state.whose_turn()
opponent = util.other(me)
own_points = state.get_points(me)
opponents_points = state.get_points(opponent)
Our main goal was to write code that was easy to read and to understand. To achieve this, we've made many methods much less efficient than they need to be. This is especially important for a project like this where many of the students are novice programmers. It is also a good principle in general, at least when you write the first version of your code.
You may feel that your bot is to slow with our State and Fleet objects for instance if you're creating an evaluating lots of State objects in a deep minimax tree. Luckily, you're not tied to our API: simply take the State object you're given and copy it to your own, more efficient, implementation. This may get you another plie or two in the search tree, so if you really want to win the competition it might be worth it.
Sure! Just remember this is not a regular project: we've tried to minimize the amount of advanced python, and the number of dependencies. So, it might be that we're aware of the potential improvement, but we haven't used it just to keep the code simple for novice programmers.
The command line scripts provide a convenient starting point, but if you want to do something more complex (like try a range of parameters for your bot), they are probably too limited.
Your best bet is to write your own script that does what you want, and have it call the engine. Have a look at the function play(...) in api/engine.py, or have it run a by itself. See experiment.py for an example.
The codebase has been rewritten entirely, so bots from last year won't work. This year the game of Schnapsen is being introduced to take the place of Planet Wars.