Making poker game with Set of tuple - python-3.x

First I have Hands = Set[Tuple[str,str]] to represents the suits and ranks of the card respectively( Hands = {("Diamonds", "4"),("Clubs","J"),...}). then I have to check if Hands contain straight flush combination(All 5 cards have the same suit in sequence.) I tried using for loop to check if all the cards have same suits but the problem is that I can't slice the element inside set. After that I am stumped. Is there a way to return a boolean that indicate whether variable Hands is straight flush?
Here is my code I have been working on
Hands = Set[Tuple[str,str]]
h = {("Diamonds", "Q"),("Diamonds","J"),("Diamonds","K"),("Diamonds","A"),("Diamonds","2")}
def is_sflush(h:Hands) -> bool:
for i in h:
if h[i][0] == h[i+1][0]: #This is where I am wrong and need help here

This sounds like a H/W problem, so not to give away the farm...
you have 2 checks to figure out: same suit and sequential. Do them separately.
For the "same suit", I recommend making a set of the suits from the cards (not the ranks), which you can do from a set comprehension. What will the size of that set tell you?
The sequential part is a bit more work. :) You might need an extra data structure that has the correct sequencing or position of the cards as something to compare against. Several strategies could work.

Related

Guess the number: Dynamic Programming -- Identifying Subproblems

I am working on the following problem and having a hell of a time at the moment.
We are playing the Guessing Game. The game will work as follows:
I pick a number between 1 and n.
You guess a number.
If you guess the right number, you win the game.
If you guess the wrong number, then I will tell you whether the number I picked is higher or lower, and you will continue guessing.
Every time you guess a wrong number x, you will pay x dollars. If you run out of money, you lose the game.
Given a particular n, return the minimum amount of money you need to guarantee a win regardless of what number I pick.
So, what do I know? Clearly this is a dynamic programming problem. I have two choices, break things up recursively or go ahead and do things bottom up. Bottom up seems like a better choice to me (though technically the max recursion depth would be 100 as we are guaranteed n<=100). The question then is: What do the sub-problems look like?
Well, I think we could start thinking about subarrays (but possible we need subsequences here) so what is the worst case in each possible sub-division kind of thing? That is:
[1,2,3,4,5,6]
[[1],[2],[3],[4],[5],[6]] -> 21
[[1,2],[3,4],[5,6]] -> 9
[[1,2,3],[4,5,6]] -> 7
...
but I don't think I quite have the idea yet. So, to get succinct since this post is kind of long: How are we breaking this up? What is the sub-problem we are trying to solve here?
Relevant Posts:
Binary Search Doesn't work in this case?

How are the bools in my while loop affecting the loop?

I'm learning Python and I built a TicTacToe game. I'm now writing unit tests and improving my code. I was advised to make a while loop in my turn function and use the following bools, but I don't know why. I can see some reason to why this makes sense, but because of how new I am I couldn't even explain why it makes any sense to me. Can someone explain why this would make more sense than another combination of bools?
print(TTTGame.player + "'s TURN!")
print('pick a number 1 through 9')
position = int(input()) - 1
valid = False<<<<<<<<<<<<<<<<<<<<<<False
while not valid:<<<<<<<<<<<<<<<<<<<<<<<<<<<Not
try:
position = int(input('pick a spot'))
except (ValueError):
print('pick a number 1 though 9')
x = TTTGame.board[position]
if x == '-':
TTTGame.board[position] = TTTGame.player
else:
print('Cant Go There!')
TTTGame.board[position] = TTTGame.player
valid = True<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<True
Based on the code you provided I would have to try to work backwards to create a worse example, and without seeing what you did initially that may cause more confusion than it would help. A fair number of the things I mention are subjective to each developer, but the principles tend to be commonly agreed upon to some degree (especially in python).
That being said I will try to explain why this pattern is optimal:
Intuitiveness: When reading this code and looking from the outside I can tell that you are doing validation, primarily this is because just reading the code as plain English I see you are assuming the input to be invalid (valid == False) and won't leave the loop until it has been validated (valid == True). Even without the additional context of knowing it was a tic-tac-toe game I can immediately tell by reading the code this is the case.
Speed: In terms of how long it takes to complete this function, it will terminate as soon as the input is valid as opposed to some other ways of doing this that require more than one check.
Pythonic: In the python community there is an emphasis on 'pythonic' code, basically this means that there are ways of doing things that are common across various types of python code. In this case there are many patterns of validating input (using for loops, terminating conditions, seperate functions etc.), but again because of how this is written I would be able to debug it without having to necessarily know your whole codebase. This also means if you see a similar chunk of code in a large project, you are more likely to recognize what's happening. It follows the principles of the zen of python in that you are being explicit, while maintaining readability, errors are not passing silently and you are keeping it simple.

Avoid impossible states with a data model for a card game in Haskell

I am trying to implement the Jass card game in Haskell and would like to make the game state as explicit as possible or avoiding impossible states with types.
The standard variant involves four players. The players opposite each other form a team.
In a game rounds are played until one team reaches the target score.
At the start of each round each player is dealt with 9 cards one player gets to choose the trump, and lead the first trick.
In a trick every player has to play one card. The cards are compared with respect to the leading suit and trump and the player with the highest card wins the trick. The points of the tricks are added to the score of the winner's team. The winner also is lead on the next trick. In a round tricks are played until each player has no cards left.
There is a more detailed explanation on wikipedia and a german explanation on jassa.at.
My data model for the player looks something like this
data Player = Player
{ playerID :: PlayerID
, name :: String
, cards :: Set Card
, sendMessage :: Message -> IO ()
, receiveAction :: IO Action
}
this way I can just use different send and receive functions for like command line or network players.
I would like the represent the game as a state machine with a pure update function, however in most states there is only one action from only one player that is valid and so i think that in the update function a big part is just handling invalid inputs.
I don't know what would be the best way to represent these parts of the game state.
The Players.
My first idea was to use a simple list and rotate this list every time so the current player is always the head. This is easy to do, but i also think it's easy for something to go wrong, like what if the list is empty, or there is only one player and so on...
Use an Array for the players and use the index for the current player. This has the advantage that to get to the next player I just have to increase the index. Somewhere i have to use mod to cycle the array but that's not really a problem. I also tried this with XDataKinds to have the size of the array on the type level and so the nextPlayer function can handel the mod. This also has the advantage that for the teams I can just use the even and odd player indices. But with this i have to store a extra Map from playerID or index to the cards of the players. So now the array and map can get out of sync.
Trick
I am not sure if i should store a list of played cards and who played them or just a record with the lead, highest card, winner and the value of the played cards and keep track of all played cards in a writer monad.
Rounds and Tricks
This is kinda the same for both, should i store a list with all played rounds and tricks or only the current round and trick and save the sum of the points from the previous rounds/tricks
There is temptation to have the type checker prove your program is perfect. However, that will become an endless pursuit. There really are not the hours in the day to spend teaching a computer how to be sure what you're sure is sure is for sure for every surety.
What I do is start with some way of solving the problem and then learn as I go what the pain points are. Which mistakes am I actually prone to making? In your case, I would implement the game (or part of) in some way I can figure out, and then from that experience I will know how to do it better.
cycle :: [a] -> [a] takes a list and repeats it forever. You can do this for your players and take the head of the list forever.
For non-empty lists there is Data.List.NonEmpty.
A way to only construct valid game states is to define an abstract data type. Rather than exporting the data constructors for a type, you only export functions of your own definition which can construct the type. That way, you can do whatever (runtime) checking or fixing you want.
Another tool is unit testing. Encoding propositions as types is difficult, especially in Haskell, and so the vast majority will not be. Instead, you can use property-based unit testing to recover a modicum of assurance.

A reverse inference engine (find a random X for which foo(X) is true)

I am aware that languages like Prolog allow you to write things like the following:
mortal(X) :- man(X). % All men are mortal
man(socrates). % Socrates is a man
?- mortal(socrates). % Is Socrates mortal?
yes
What I want is something like this, but backwards. Suppose I have this:
mortal(X) :- man(X).
man(socrates).
man(plato).
man(aristotle).
I then ask it to give me a random X for which mortal(X) is true (thus it should give me one of 'socrates', 'plato', or 'aristotle' according to some random seed).
My questions are:
Does this sort of reverse inference have a name?
Are there any languages or libraries that support it?
EDIT
As somebody below pointed out, you can simply ask mortal(X) and it will return all X, from which you can simply pick a random one from the list. What if, however, that list would be very large, perhaps in the billions? Obviously in that case it wouldn't do to generate every possible result before picking one.
To see how this would be a practical problem, imagine a simple grammar that generated a random sentence of the form "adjective1 noun1 adverb transitive_verb adjective2 noun2". If the lists of adjectives, nouns, verbs, etc. are very large, you can see how the combinatorial explosion is a problem. If each list had 1000 words, you'd have 1000^6 possible sentences.
Instead of the deep-first search of Prolog, a randomized deep-first search strategy could be easyly implemented. All that is required is to randomize the program flow at choice points so that every time a disjunction is reached a random pole on the search tree (= prolog program) is selected instead of the first.
Though, note that this approach does not guarantees that all the solutions will be equally probable. To guarantee that, it is required to known in advance how many solutions will be generated by every pole to weight the randomization accordingly.
I've never used Prolog or anything similar, but judging by what Wikipedia says on the subject, asking
?- mortal(X).
should list everything for which mortal is true. After that, just pick one of the results.
So to answer your questions,
I'd go with "a query with a variable in it"
From what I can tell, Prolog itself should support it quite fine.
I dont think that you can calculate the nth solution directly but you can calculate the n first solutions (n randomly picked) and pick the last. Of course this would be problematic if n=10^(big_number)...
You could also do something like
mortal(ID,X) :- man(ID,X).
man(X):- random(1,4,ID), man(ID,X).
man(1,socrates).
man(2,plato).
man(3,aristotle).
but the problem is that if not every man was mortal, for example if only 1 out of 1000000 was mortal you would have to search a lot. It would be like searching for solutions for an equation by trying random numbers till you find one.
You could develop some sort of heuristic to find a solution close to the number but that may affect (negatively) the randomness.
I suspect that there is no way to do it more efficiently: you either have to calculate the set of solutions and pick one or pick one member of the superset of all solutions till you find one solution. But don't take my word for it xd

Alpha-Beta cutoff

I understand the basics of this search, however the beta cut-off part is confusing me, when beta <= value of alphabeta I can either return beta, break, or continue the loop.
return beta doesn't seem to work properly at all, it returns the wrong players move for a different state of the board (further into the search tree)
break seems to work correctly, it is very fast but it seems a bit TOO fast
continue is a lot slower than break but it seems more correct...I'm guessing this is the right way but pseudocode on google all use 'break' but because this is pseudocode I'm not sure what they mean by 'break'
Just for the fun of it I'm going to guess that you're talking about Minimax with Alpha-Beta cutoff, where
ALPHA-BETA cutoff is a method for
reducing the number of nodes explored
in the Minimax strategy. For the nodes
it explores it computes, in addition
to the score, an alpha value and a
beta value.
Here is a page that describes this method and also provides a link to a C program that implements this method. Hopefully something here helps you with your problem, if I'm totally off with my guess please give more detail in your question.
function MINIMAX(N) is
begin
if N is a leaf then
return the estimated score of this leaf
else
Let N1, N2, .., Nm be the successors of N;
if N is a Min node then
return min{MINIMAX(N1), .., MINIMAX(Nm)}
else
return max{MINIMAX(N1), .., MINIMAX(Nm)}
end MINIMAX;
Beta cutoffs occur when the branch you are currently searching is better for your opponent than one you've already searched. It was once explained to me as follows:
suppose are fighting with your enemy, and you consider a number of your choices.
After fully searching the best possible outcome of your first choice (throwing a punch), you determine the result is your opponent will eventually poke you in the eye. We'll call this beta... the best your opponent can do so far. Obviously, you would like to find a result that does better.
Now we consider your next option (running away in disgrace). When exploring your opponents first possible reply, we find that the best possible outcome is you are shot in the back with a gun. This is where a beta cutoff is triggered... we stop searching the rest of your opponents moves and return beta, because we really don't care if you find in searching his other replies he can also nuke you... you would already opt for the poke in the eye from the previous option.
Now specifically what this means is your program should return beta... if it doesn't work, you should compare to an alpha-beta search algorithm elsewhere.

Resources