/usr/share/gnome-hearts/stock_ai.py is in gnome-hearts 0.3-2.1ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | # Hearts - stock_ai.py
# Copyright 2006 Sander Marechal
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# This is a simple stock AI used for the standard players and the "hint" feature. It's not too
# smart overall, but it works.
from definitions import *
from player import Player
from player_api import *
class StockAI(Player):
"""This is the default AI for gnome-hearts"""
def s_points_and_high_spades(self, a, b):
"""
Similar to the standard s_points sorting function, but this counts the King and Ace
of Spades as point cards as well, making sure the player tries to get rid of them.
"""
if a == (spades, queen): return 1
if b == (spades, queen): return -1
if a == (spades, ace_high): return 1
if b == (spades, ace_high): return -1
if a == (spades, king): return 1
if b == (spades, king): return -1
if a[0] == hearts and b[0] != hearts: return 1
if b[0] == hearts and a[0] != hearts: return -1
return a[1] - b[1]
def s_spades_priority(self, a, b):
""" spade priority = J,10,9,8,7,6,5,4,3,2,A,K,Q followed by the other suits """
if a[0] == spades and b[0] != spades: return 1
if b[0] == spades and a[0] != spades: return -1
if a[1] >= queen and b[1] < queen: return 1
if b[1] >= queen and a[1] < queen: return -1
return b[1] - a[1]
def select_cards(self, direction):
"""Return a list of three cards hat will be passed to an opponent"""
result = []
def select(card):
result.append(card)
self.hand.remove(card)
# First pass on the high spades
if (spades, queen) in self.hand: select((spades, queen))
if (spades, king) in self.hand: select((spades, king))
if (spades, ace_high) in self.hand: select((spades, ace_high))
# Pass off the other cards
while len(result) < 3:
clubs_list = filter(f_clubs, self.hand)
diamonds_list = filter(f_diamonds, self.hand)
hearts_list = filter(f_hearts, self.hand)
# If we can clear a suit with one card then do so, else pick a hearts or a high card
if len(clubs_list) == 1:
select(clubs_list[0])
elif len(diamonds_list) == 1:
select(diamonds_list[0])
elif len(hearts_list):
hearts_list.sort(s_rank, reverse=True)
select(hearts_list[0])
else:
self.hand.sort(s_rank, reverse=True)
select(self.hand[0])
return result
def play_card(self):
"""Play a card"""
valid_cards = filter(self.f_valid, self.hand)
# Open with the lowest valid card
if self.trick.num_played == 0:
valid_cards.sort(s_rank)
#prevent scenario where, for example, player has QoS and KoS left - it will play QoS w/o the below check
if valid_cards[0] == (spades, queen) and len(valid_cards) > 1:
return valid_cards[1]
return valid_cards[0]
# Someone has already played. If the score is zero, it's not a point card
if trick_get_score() == 0:
# If we have a trump suit, take it with the highest card
if have_suit(self.hand, self.trick.trump):
valid_cards.sort(s_rank, reverse=True)
# Spades are special because of the Queen
if (self.trick.trump == spades):
# Try dumping the Queen on someone else
if (spades, king) in self.trick.card and (spades, queen) in valid_cards: return (spades, queen)
if (spades, ace_high) in self.trick.card and (spades, queen) in valid_cards: return (spades, queen)
if self.trick.num_played == 3:
# We're the last one playing and the queen isn't on the trick.
# Take it with the Ace, King or anything below the Queen
if valid_cards[0] == (spades, queen) and len(valid_cards) > 1:
return valid_cards[1]
return valid_cards[0]
# Other people still have to play. Try not to play the Queen or anything above
# because we may end up taking the points
valid_cards.sort(self.s_spades_priority)
return valid_cards[0]
# Trump is diamonds or clubs. Play highest cards
return valid_cards[0]
# We don't have a trump. Dump a point card
valid_cards.sort(self.s_points_and_high_spades, reverse=True)
return valid_cards[0]
# There are point cards on the trick
if have_suit(self.hand, self.trick.trump):
# Play the highest card that doesn't take the trick
high_card = self.trick.get_highest_card()
valid_cards.sort(s_rank, reverse=True)
for card in valid_cards:
if card[0] != high_card[0] or card[1] < high_card[1]: return card
# We are forced to take the trick. Play highest card if we're the last player
if self.trick.num_played == 3:
if valid_cards[0] == (spades, queen) and len(valid_cards) > 1:
return valid_cards[1]
else:
return valid_cards[0]
# Play low. Someone may beat us yet
valid_cards.sort(s_rank)
return valid_cards[0]
else:
# We don't have a trump. Dump a point card
valid_cards.sort(self.s_points_and_high_spades, reverse=True)
return valid_cards[0]
|