Déterminer la victoire dans Tictactoe

19

Jouons au golf à code!

Étant donné un état de carte tic-tac-toe (exemple :)

|x|x|o|
|x|o|x|
|o|o|x|

Déterminez si un jeu est un wina loseou un cat. Votre code doit afficher l'une de ces options en fonction d'un état. Le jeu ci-dessus devrait sortirlose

Juste pour être clair: une victoire est définie comme 3 xs consécutifs (diagonale, horizontale, verticale). une défaite est de 3 os d'affilée, tandis qu'un catmatch en aucun d'affilée.

Pour rendre les choses intéressantes, vous devez déterminer votre structure d'entrée pour l'état, que vous devez ensuite expliquer. Par exemple, xxoxoxooxest un état valide comme vu ci-dessus où chacun des caractères est lu de gauche à droite, de haut en bas. [['x','x','o'],['x','o','x'],['o','o','x']]est le jeu en tableau multidimensionnel lu de manière similaire. Alors que 0x1a9ce qui est hexadécimal 110101001pourrait fonctionner comme une compression appropriée où 1peut être manipulé pour xs et 0peut être manipulé pour o.

Mais ce ne sont que quelques idées, je suis sûr que vous pourriez en avoir plusieurs.

Règles de base:

  1. Votre programme doit pouvoir accepter n'importe quel état viable.
  2. La forme d'entrée doit pouvoir représenter n'importe quel état.
  3. "L'état de victoire doit être déterminé à partir du tableau"
  4. Supposons une planche complète
  5. Winavant losepar exemple dans le cas «xxxoooxxx»

Le nombre de personnages le plus bas gagne

Dylan Madisetti
la source
1
J'aime cette structure de saisie:, (win|lose|cat) [xo]{9}où le premier mot indique si le jeu est une victoire, une perte ou un chat (?) Pour le joueur x. Capable de représenter n'importe quel état.
Runer112
2
Puis-je suggérer une règle comme "L'état gagnant doit être déterminé à partir du tableau" ou "L'entrée ne doit contenir aucune information à l'exception de l'état du tableau"?
undergroundmonorail
3
Supposons-nous que seuls les jeux légaux sont joués? Si c'est le cas, certains États seraient impossibles, par exemple XXX OOO XXX, mais sinon certains États en pension complète incluent cela comme un quatrième résultat impossible, où X gagne mais O gagne également.
Riot
10
pourquoi "chat" par intérêt?
Chris
7
@DylanMadisetti: jamais entendu auparavant et googlign pour "gagner perdre chat" n'a rien trouvé. Je serais allé avec une cravate ou un tirage personnellement. Ou dans le cas de ce jeu peut-être "l'inévitabilité". ;-) Cela ne me dérange pas beaucoup en ce qui concerne la compétition. Une chaîne est une chaîne. ;-)
Chris

Réponses:

11

Ruby 2.0, 85 caractères

Voici une solution simple basée sur un masque de bits dans Ruby:

d=gets.hex
$><<[292,146,73,448,56,7,273,84].map{|m|d&m<1?:lose:d&m<m ?:cat: :win}.max

La carte est représentée par un nombre hexadécimal, composé de neuf bits correspondant aux neuf carrés. 1 est un X, 0 est un O. C'est exactement comme l' 0x1a9exemple de la question, bien que le 0xsoit facultatif!

Il y a probablement une meilleure façon de faire les masques de bit que de coder en dur une grande liste. Je prendrai volontiers des suggestions.

Voir courir sur Ideone ici .

Paul Prestidge
la source
1
Votre liste contient 273deux fois. Et j'aime vraiment l' maxidée!
Ventero
1
Oh @Ventero, toujours avec les optimisations obscures (merci)
Paul Prestidge
Il peut y avoir des espaces vides sur un tableau. Votre format d'entrée ne tient pas compte de cela et ne peut donc pas représenter un état de jeu viable.
Stephen Ostermiller
2
@StephenOstermiller règle 4: supposez un tableau complet. Vous avez raison de dire que cette règle est peut-être contredite par les règles 1 et 2, mais si vous lisez tous les commentaires sur la question, je pense que c'est dans l'esprit de la question (les tableaux incomplets ne sont pas couverts, tandis que les tableaux complets mais illégaux le sont.) Cependant, je pense que l'octal serait un format d'entrée plus convivial que l'hex.
Level River St
1
Compris, je pensais que complet signifiait quelque chose de différent.
Stephen Ostermiller
10

Mathematica, 84 caractères

a=Input[];Which[Max@#>2,win,Min@#<1,lose,1>0,cat]&@{Tr@a,Tr@Reverse@a,Tr/@a,Total@a}

Format d'entrée: {{1, 1, 0}, {1, 0, 1}, {0, 0, 1}}

alephalpha
la source
Qu'est-ce qu'il se passe ici?
seequ
3
@TheRare Commencez par la droite. Tr@aest la trace du champ (somme sur diagonale), Tr@Reverse@aest la trace du champ inversé (certains sur anti-diagonale), Tr/@aest Trappliquée à chaque ligne, ce qui vous donne la somme sur chaque ligne, Total@avous donne la somme sur chaque colonne. Donc, fondamentalement, vous avez les 8 lignes à vérifier. Ensuite, la Whichchose est appliquée à cela (essentiellement une if/elseif/elsedéclaration), où #représente cette liste de 8 valeurs. ifil y a un 3vous gagnez, else ifil y a un 0vous perdez, else if 1>0(vrai) cat.
Martin Ender
6

Bash: 283 262 258

Doté d'une interface relativement conviviale.

t(){ sed 's/X/true/g;s/O/false/g'<<<$@;}
y(){ t $(sed 's/X/Q/g;s/O/X/g;s/Q/O/g'<<<$@);}
f(){($1&&$2&&$3)||($1&&$5&&$9)||($1&&$4&&$7)||($2&&$5&&$8)||($3&&$5&&$7)||($3&&$6&&$9)||($4&&$5&&$6)||($7&&$8&&$9)}
f $(t $@)&&echo win||(f $(y $@)&&echo lose)||echo cat

Éxécuter bash tictactoe.sh O X O X O X X O X

Remarque: la liste des 9 positions est une représentation matricielle standard. Peu importe si le tableau est représenté comme une colonne majeure ou une ligne majeure, lue de gauche à droite ou de haut en bas - les jeux de noughts et de croix (ou tic tac toe si vous insistez) sont symétriques, donc l'ordre d'entrée ne devrait pas être pertinent au résultat dans chaque implémentation correcte, tant que l'entrée est linéaire.

Edit: Merci à hjk pour une suggestion de syntaxe de fonction plus courte.

Émeute
la source
Considérez t() { ... }au lieu de function t? Peut y sauvegarder certains personnages. :)
hjk
J'avais totalement oublié la syntaxe des fonctions alternatives - merci!
Riot
Les espaces ne sont pas nécessaires <<<pour enregistrer quatre autres caractères.
Michael Mior
4

Befunge 93 - 375

Prend une chaîne binaire en entrée.

99>~\1-:!!|>v  
>0v>v>v   >^$>v
^+ + +    0<:p:
>#+#+#+    ^246
^+ + +    0<265
>#+#+#+    ^pp6
^+ + +    0<2++
 #+#+#+     55p
   0 0      552
  >^>^>0v   +46
v+ + +  <   ppp
>0 + + + v  444
   v!!-3:<< 246
  v_"ni"v   ppp
  0v" w"<   :+:
  \>,,,,@   266
  ->,,,@    555
  !^"cat"_^ 645
  !>:9-! ^  +:+
  >|        p:p
   >"eso"v  6p6
 @,,,,"l"<  246
            p2p
            >^ 
  v       <^  <

Lit la chaîne. Bruteforce l'écrit (la bande la plus à droite verticale) comme matrice entre les

^+ + + 
>#+#+#+
^+ + + 
>#+#+#+
^+ + + 
 #+#+#+

ajout d'un treillis (idk). Détermine la somme des colonnes, des lignes et de deux diagnostics. Compare ces valeurs à 3 ("gagner") ou à 0 ("perdre"), sinon si toutes les valeurs sont égales à 1 ou 2, dessinez ("chat").

AndoDaan
la source
4

GolfScript, 27 caractères

70&.{~"win""lose"if}"cat"if

Le format d'entrée est une chaîne composée de huit chiffres octaux, chacun codant (de manière redondante) trois carrés de carte consécutifs:

  • Les trois premiers chiffres codent chacun une seule rangée de la carte, de haut en bas et de gauche à droite.
  • Les trois chiffres suivants codent chacun une seule colonne de la carte, de gauche à droite et de haut en bas.
  • Les deux derniers chiffres codent chacun une des diagonales (d'abord du haut à gauche au bas à droite, puis du bas à gauche au haut à droite).

Pour coder une séquence (ligne / colonne / diagonale) de trois carrés en tant que chiffre octal, remplacez chaque xdans la séquence par un 1 et chaque opar un 0, et interprétez la séquence résultante de uns et de zéros comme un nombre binaire compris entre 0 et 7 compris.

Ce format d'entrée est tout à fait redondante (toutes les positions du conseil d'administration sont codées au moins deux fois, la position centrale codé quatre fois), mais elle ne représente sans ambiguïté tout état possible d'un complètement rempli carte tic-tac-toe, et n'a pas directement encode la gagnant dans l'entrée.

L'entrée peut, facultativement, contenir des espaces ou d'autres délimiteurs entre les chiffres. En fait, tout le programme se soucie vraiment de savoir si la chaîne d'entrée contient ou non les chiffres 7ou0 .

Par exemple, l'exemple de carte:

|x|x|o|
|x|o|x|
|o|o|x|

peut être représenté par l'entrée:

651 643 50

Pour plus de commodité, voici un programme GolfScript pour convertir une disposition de tableau d'art ASCII, comme indiqué dans le défi ci-dessus, en une chaîne d'entrée adaptée à ce programme:

."XOxo"--[{1&!}/]:a[3/.zip"048642"{15&a=}%3/]{{2base""+}%}%" "*

Ce convertisseur ignore tous les caractères autres que xeto , dans les deux cas, dans son entrée. Il produit une chaîne à un chiffre (complète avec des délimiteurs d'espace comme indiqué ci-dessus) appropriée pour alimenter le programme déterminant la victoire ci-dessus, de sorte que la concaténation de ces deux programmes peut être utilisée pour déterminer le gagnant directement à partir du tableau d'art ASCII.

En outre, voici un convertisseur inversé, juste pour démontrer que l'entrée représente effectivement sans équivoque la carte:

.56,48>-- 3<{2base-3>{"ox"=}%n}%"|".@@*+);

Ps. Voici une démonstration en ligne de cette solution.

Ilmari Karonen
la source
2
Le format d'entrée semble être un peu une triche car une grande partie du travail se produit dans la production de l'entrée.
Arkku
@Arkku: Eh bien, oui, mais la question dit explicitement que "vous devez déterminer votre structure d'entrée pour l'état - que vous devez ensuite expliquer." Il montre même une chaîne hexadécimale binaire comme exemple d'un format d'entrée valide; la seule différence entre cela et mon format d'entrée est que je réorganise et duplique certains bits.
Ilmari Karonen du
6
C'est exactement la duplication qui semble être une triche. (par exemple, il ne codent directement le gagnant en présence de 7 ou 0 à l'entrée)
Arkku
C'est quand même un encodage intelligent, c'est redondant, mais rend la recherche de la solution beaucoup plus efficace que n'importe quel encodage non redondant!
ARRG
3

Python 2 - 214 octets

b=eval(raw_input())
s=map(sum,b)
w,l='win','lose'
e="if min(s)<1:print l;a\nif max(s)>2:print w;a"
exec e+'\ns=map(sum,zip(*b))\n'+e
m=b[1][1]
for i in 0,2:
 if m==b[0][i]==b[2][abs(i-2)]:print[l,w][m];a
print'cat'

Je suis sûr qu'il y a des améliorations à apporter.

Courir:

python2 tictactoe.py <<< '[[1,1,1],[1,0,1],[0,1,0]]'

qui représente ce conseil:

X|X|X
-----
X|O|X
-----
0|X|0

Quitte avec une NameErrorexception dans tous les cas sauf cat.

métro monorail
la source
Whoa, je n'ai jamais su <<<! +1 juste pour ça.
Greg Hewgill
@GregHewgill C'est assez pratique. ./whatever <<< 'blah blah blah'est le même que, echo -n 'blah blah blah' | ./whatevermais sans avoir un processus distinct pour echo.
undergroundmonorail
@undergroundmonorail echoin bashest en fait une fonction intégrée, donc ne crée pas de nouveau processus
Bob
@GregHewgill ça s'appelle une chaîne héréditaire
3

Haskell, 146 caractères

Pour rendre les choses intéressantes, vous devez déterminer votre structure d'entrée pour l'état, que vous devez ensuite expliquer.

D'ACCORD :). Ma représentation d'un tableau est l'un de ces 126 caractères

ĻŃŇʼnŊœŗřŚşšŢťŦŨųŷŹźſƁƂƅƆƈƏƑƒƕƖƘƝƞƠƤƳƷƹƺƿǁǂDždžLjǏǑǒǕǖǘǝǞǠǤǯDZDzǵǶǸǽǾȀȄȍȎȐȔȜȳȷȹȺȿɁɂɅɆɈɏɑɒɕɖɘɝɞɠɤɯɱɲɵɶɸɽɾʀʄʍʎʐʔʜʯʱʲʵʶʸʽʾˀ˄ˍˎː˔˜˭ˮ˰˴˼̌

Voici la solution en 146 caractères:

main=interact$(\x->case(head x)of h|elem h "ĻŃœťŦŨųŷŹƁƂƅƈƕƠƤƳƿǂdžǞǤǵǾȀȳȿɁɅɑɒɘɝɠɤɵɽʀʐʽʾː˭ˮ˰˴˼̌"->"lose";h|elem h "ƏƝƞƹǁLjǑǝȍȺɆɈɶɾʎʸ"->"cat";h->"win")

Et voici comment cela fonctionne, en tant que script haskell:

import Data.List (subsequences, (\\))
import Data.Char (chr)

-- A set of indexes [0-8] describing where on the board pieces of a single color have been played
-- For example the board "OxO;Oxx;xxO" is indexes [0,2,3,8]
type Play = [Int]

-- There are 126 filled tic tac toe boards when X plays first.
--      (This is a combination of 4 OHs among 9 places : binomial(9 4) = 126)
-- perms returns a list of all such possible boards (represented by the index of their OHs).
perms = filter (\x -> 4 == length x) $ subsequences [0..8]

-- We now create an encoding for plays that brings them down to a single char.
-- The index list can be seen as an 9 bit binary word [0,2,3,8] -> '100001101'
-- This, in turn is the integer 269. The possible boards give integers between 15 and 480.
-- Let's call those PlayInts
type PlayInt = Int

permToInt [] = 0
permToInt (x:xs) = (2 ^ x) + permToInt xs 

-- Since the characters in the range 15-480 are not all printable. We offset the chars by 300, this gives the range 
-- ĻŃŇʼnŊœŗřŚşšŢťŦŨųŷŹźſƁƂƅƆƈƏƑƒƕƖƘƝƞƠƤƳƷƹƺƿǁǂDždžLjǏǑǒǕǖǘǝǞǠǤǯDZDzǵǶǸǽǾȀȄȍȎȐȔȜȳȷȹȺȿɁɂɅɆɈɏɑɒɕɖɘɝɞɠɤɯɱɲɵɶɸɽɾʀʄʍʎʐʔʜʯʱʲʵʶʸʽʾˀ˄ˍˎː˔˜˭ˮ˰˴˼̌
-- Of all distinct, printable characters
uOffset = 300

-- Transform a PlayInt to its Char representation
pIntToUnicode i = chr $ i + uOffset

-- Helper function to convert a board in a more user friendly representation to its Char
-- This accepts a representation in the form "xooxxxoxo"
convertBoard s = let play = map snd $ filter (\(c, i) -> c == 'o') $ (zip s [0..]) :: Play 
    in pIntToUnicode $ permToInt play

--
-- Now let's cook some data for our final result
--  

-- All boards as chars
allUnicode = let allInts = map permToInt perms 
    in map pIntToUnicode allInts

-- Now let's determine which boards give which outcome.

-- These are all lines, columns, and diags that give a win when filled
wins = [
        [0,1,2],[3,4,5],[6,7,8], -- lines
        [0,3,6],[1,4,7],[2,5,8], -- columns
        [0,4,8],[2,4,6] -- diagonals
    ]

isWin :: Play -> Bool   
isWin ps = let triplets = filter (\x -> 3 == length x) $ subsequences ps -- extract all triplets in the 4 or 5 moves played
    in any (\t -> t `elem` wins) triplets -- And check if any is a win line

-- These are OH wins
oWins = filter isWin perms
-- EX wins when the complement board wins
xWins = filter (isWin . complement) perms
    where complement ps = [0..9] \\ ps
-- And it's stalemate otherwise
cWins = (perms \\ oWins) \\ xWins

-- Write the cooked data to files
cookData = let toString = map (pIntToUnicode . permToInt) in do
  writeFile "all.txt" allUnicode
  writeFile "cWins.txt" $ toString cWins
  writeFile "oWins.txt" $ toString oWins
  writeFile "xWins.txt" $ toString xWins

-- Now we know that there are 48 OH-wins, 16 stalemates, and 62 EX wins (they have more because they play 5 times instead of 4).
-- Finding the solution is just checking to which set an input board belongs to (ungolfed :)
main = interact $ \x -> case (head x) of -- Only consider the first input char
    h | elem h "ĻŃœťŦŨųŷŹƁƂƅƈƕƠƤƳƿǂdžǞǤǵǾȀȳȿɁɅɑɒɘɝɠɤɵɽʀʐʽʾː˭ˮ˰˴˼̌" -> "lose" -- This string is == oWins
    h | elem h "ƏƝƞƹǁLjǑǝȍȺɆɈɶɾʎʸ" -> "cat" -- And this one == cWins
    h -> "win"
ARRG
la source
3

JavaScript, 420 caractères

if((s&0x3F000)==0x3F000||(s&0x00FC0)==0x00FC0||(s&0x0003F)==0x0003F||(s&0x030C3)==0x030C3||(s&0x0C30C)==0x0C30C||(s&0x30C30)==0x30C30||(s&0x03330)==0x03330||(s&0x30303)==0x30303)return 'win'
if((s&0x3F000)==0x2A000||(s&0x00FC0)==0x00A80||(s&0x0003F)==0x0002A||(s&0x030C3)==0x02082||(s&0x0C30C)==0x08208||(s&0x30C30)==0x20820||(s&0x03330)==0x02220||(s&0x30303)==0x20202)return 'lose'
if((s&0x2AAAA)==0x2AAAA)return 'cat'

Dans cette version, s contient un entier qui représente l'état du plateau de jeu. Il s'agit d'un tableau de valeurs où deux bits représentent chaque carré de la carte:

  • 10 - X
  • 11 - O
  • 00 - Carré vide

Cette solution utilise la manipulation de bits pour tester chacune des huit configurations "trois dans une rangée" possibles (elle les teste chacune deux fois, une fois pour X et une fois pour O).

Je présente cela avec une minification mineure de mon site Web Tic-Tac-Toe où cette detectWinfonction est utilisée dans le cadre d'un vrai jeu Tic-Tac-Toe.

Stephen Ostermiller
la source
6
Eh bien, cela pourrait être appelé brute le forçant.
seequ
2

Ruby, 84 caractères

$><<(gets.tr("01","10")[r=/0..(0|.0.)..0|000(...)*$|^..0.0.0/]?:win:~r ?:lose: :cat)

Solution simple basée sur RegExp. Le format d'entrée est une chaîne binaire à 9 chiffres, par exemple110101001 pour l'exemple de carte donné dans la question.

Ruby, 78 caractères

$><<(gets.tr("ox","xo")[r=/o...(o|.o.)...o|ooo|o_.o._o/]?:win:~r ?:lose: :cat)

Format d'entrée: xxo_xox_oox

Ventero
la source
1

Haskell, 169

main=interact$(\x->last$"cat":[b|(a,b)<-[("ooo","lose"),("xxx","win")],any(==a)x]).(\x->x++(foldr(zipWith(:))(repeat[])x)++map(zipWith(!!)x)[[0..],[2,1,0]]).take 3.lines

Format d'entrée: "X" est représenté uniquement par x, "O" uniquement par o. Dans chaque ligne, les caractères sont simultanés sans espaces, etc. Les lignes sont séparées par de nouvelles lignes.

Génère toutes les lignes / colonnes / diagonales possibles, puis filtre [("ooo","lose"),("xxx","win")]par leur existence sur le tableau, puis sélectionne le deuxième mot du tuple, afin que nous sachions quels joueurs ont gagné. Nous préfixons "cat"afin de pouvoir prendre le dernier élément de la liste comme gagnant. Si les deux joueurs ont gagné, ce "win"sera le dernier (les compréhensions de liste maintiennent l'ordre). Puisque "cat"c'est toujours le premier, si un gagnant existe, il sera choisi, mais sinon un dernier élément existe toujours comme pré-ajouté"cat" garantit la non- .

EDIT: Rasé 3 caractères en changeant la compréhension de la dernière liste en map.

YawarRaza7349
la source
1

C, 150 environ

Il est minuit ici et je n'ai fait aucun test , mais je posterai quand même le concept. J'y reviendrai demain.

L'utilisateur entre deux nombres octaux (je voulais utiliser le binaire mais pour autant que je sache, C ne prend en charge que l'octal):

a représente le carré central, 1 pour un X, 0 pour un O

b est un nombre à neuf chiffres représentant les carrés du périmètre, encerclant le tableau en commençant dans un coin et se terminant dans le même coin (avec répétition de ce coin uniquement), 1 pour un X, 0 pour un O.

Il y a deux façons de gagner:

  1. le carré central est X ( a= 1) et deux carrés opposés sont également X ( b&b*4096est différent de zéro)

  2. trois carrés de périmètre adjacents sont X ( b/8 & b & b*8est différent de zéro). Ce n'est une victoire valide que si le carré du milieu est un carré de bord, pas un carré de coin, il est donc nécessaire d'appliquer le masque mégalement, pour éviter les cas de carrés de coin.

La perte est détectée à l'aide de la variable c, qui est l'inverse de b.

int a,b,c,m=010101010;
main(){
    scanf("%o%o",a,b);c=b^0111111111;
    printf("%s",(a&&b&b*4096)|(b/8&b&b*8&m)?"win":((!a&&c&c*4096)|(c/8&c&c*8)?"lose":"cat"));
}
Level River St
la source
Vous avez oublié d'appliquer le masque mdans la détection de "perte" - c/8&c&c*8. J'ai re-golfé votre code (sans tester son fonctionnement) comme suit: int a,b;t(v){return a&&v&v<<12||v/8&v&v*8&0x208208;}main(){scanf("%o%o",a,b);printf("%s",t(b)?"win":t(b^0x1249249)?"lose":"cat");}(130 caractères). Le test répété était suffisamment long pour être extrait dans une fonction de test t(); cela supprime le besoin de cet m; les constantes converties en hex pour enregistrer un char chacune.
Toby Speight
Je viens de remarquer que le printfn'a pas besoin d'une chaîne de format - il suffit de fournir la chaîne de résultat comme format - ou putscela, car la question ne demande pas de nouvelle ligne après la sortie! (enregistre 7 caractères supplémentaires).
Toby Speight
1

Frapper, 107 103

Génère et exécute un script sed.

Format d'E / S: oxo-oox-xoosorties lose(utilisez un -pour séparer les lignes). Entrée sur stdin. Nécessite GNU sed pour la ccommande.

J'ai interprété la règle 5 comme "si gagner et perdre sont possibles, choisissez gagner".

Code principal

Telle est la vraie réponse.

Rien d'intéressant vraiment. Il définit $bcomme /cwinpour sauver des caractères, définit alors la partie de condition de victoire du script, puis utilise sed y/x/o/\;s$b/close/pour convertir xà oet cwinà close(générant ainsi les conditions lose). Il envoie ensuite les deux choses et ccat(qui sortira catsi aucune condition gagnant / perdant ne correspond) à sed.

b=/cwin
v="/xxx$b
/x...x...x$b
/x..-.x.-..x$b
/x-.x.-x$b"
sed "$v
`sed y/x/o/\;s$b/close/<<<"$v"`
ccat"

Code généré

Il s'agit du script sed généré et exécuté par le script Bash.

Dans les expressions régulières, .correspond à n'importe quel caractère et après euxcTEXT imprime TEXTE et se termine si l'expression rationnelle correspond.

Cela peut fonctionner comme un script sed autonome. Il fait 125 caractères, vous pouvez le compter comme une autre solution.

/xxx/cwin
/x...x...x/cwin
/x..-.x.-..x/cwin
/x-.x.-x/cwin
/ooo/close
/o...o...o/close
/o..-.o.-..o/close
/o-.o.-o/close
ccat

la source
1

Python 3, 45

L'entrée est en i , qui est une liste de nombres représentant chaque ligne, colonne et diagonale du plateau de jeu, par exemple:

X X O
O X O
O O X

est représenté par [6, 2, 1, 4, 6, 1, 7, 4] .

Code :('cat','lose','win')[2 if 7 in i else 0 in i]

pseudonyme117
la source
1

Fléchette - 119

(Voir dartlang.org ).

Version originale utilisant RegExp: 151 caractères.

main(b,{w:"cat",i,p,z}){
 for(p in["olose","xwin"])
   for(i in[0,2,3,4])
     if(b[0].contains(new RegExp('${z=p[0]}(${'.'*i}$z){2}')))
       w=p.substring(1);
  print(w);
}

L'entrée sur la ligne de commande est de 11 caractères, par exemple, "xxx | ooo | xxx". Tout caractère non xo peut être utilisé comme délimiteur.

Les espaces blancs de début et les retours à la ligne doivent être omis avant de compter les caractères, mais j'ai coupé les espaces internes dans la mesure du possible. Je souhaite qu'il y ait une façon plus petite de faire la sous-chaîne.

Version à base de bits récursive: 119 caractères. L'entrée doit être un nombre de 9 bits avec 1 représentant «x» et 0 représentant «o».

main(n){
  n=int.parse(n[0]);
  z(b,r)=>b>0?b&n==b&511?"win":z(b>>9,n&b==0?"lose":r):r;
  print(z(0x9224893c01c01e2254,"cat"));
}
lrn
la source
1

CJam, 39 38 36 caractères

"ᔔꉚ굌궽渒䗠脯뗠㰍㔚귇籾〳㎪䬔⹴쪳儏⃒ꈯ琉"2G#b129b:c~

Ceci est un code converti de base pour

q3/_z__Wf%s4%\s4%]`:Q3'o*#"win"{Q'x3*#"lose""cat"?}?

qui fait 52 caractères.

L'entrée est simplement la représentation sous forme de chaîne de la carte à partir du coin supérieur gauche, en allant ligne par ligne. Par exemple:

oxooxooox

ce qui se traduit par une winsortie. Ou

oxooxoxox

ce qui se traduit par une catsortie, etc.

Le code fait simplement les trois choses suivantes:

  • q3/_ - Divisez la chaîne en parties de 3, c'est-à-dire par ligne
  • _z - Copiez le tableau par ligne et transposez-le en tableau par colonne.
  • __Wf%s4%- Inversez chaque rangée et obtenez la diagonale de gauche à droite. Il s'agit de la diagonale secondaire de la carte.
  • \s4% - Obtenez la diagonale principale de la planche
  • ]` - Envelopper tout dans le tableau et stringifier le tableau.

Maintenant, nous avons tous les groupes possibles de 3 du conseil d'administration. Nous vérifions simplement l'existence de "ooo" et "xxx" pour déterminer le résultat.

Essayez-le en ligne ici

Optimiseur
la source
1

GNU sed, 25 octets

Si l'entrée est une représentation redondante du tableau avec des vues distinctes pour les colonnes, les lignes et les diagonales, comme cela est également utilisé dans d'autres réponses, alors sed est très bien adapté pour vérifier l'état final du jeu avec le moins d'octets.

Format d'entrée: xxx ooo xxx xox xox xox xox xox (état de la carte tiré de la question du PO)

/xxx/cwin
/ooo/close
ccat

Si le format d'entrée n'est pas redondant ( xxx ooo xxx), le code sed ci-dessus ne fonctionne que s'il est ajouté par la ligne ci-dessous, ce qui rend le programme de 96 octets (avec l' rindicateur nécessaire compté).

s/(.)(.)(.) (.)(.)(.) (.)(.)(.)/& \1\4\7 \2\5\8 \3\6\9 \1\5\9 \3\5\7/
seshoumara
la source
1

Bash: 208 caractères

y(){ tr '01' '10'<<<$@;}
f(){ x=$[($1&$2&$3)|($1&$5&$9)|($1&$4&$7)|($2&$5&$8)|($3&$5&$7)|($3&$6&$9)|($4&$5&$6)|($7&$8&$9)]; }
f $@;w=$x
f $(y $@)
([ $x -eq 1 ]&&echo lose)||([ $w -eq 1 ]&&echo win)||echo cat

Éxécuter bash tictactoe.sh 0 1 0 1 0 1 1 0 1

Inspiré par cette réponse .

Michael Mior
la source
0

VB.net

Avec l'exemple, est codé comme le modèle de bits suivant

q  = &B_100101_100110_011010 ' 00 Empty, 01 = O, 10 = X

Nous pouvons maintenant déterminer le résultat (ou le gagnant) en procédant comme suit.

Dim g = {21, 1344, 86016, 66576, 16644, 4161, 65379, 4368}
Dim w = If(g.Any(Function(p)(q And p)=p),"Lose",If(g.Any(Function(p)(q And p*2)=p*2),"Win","Cat"))
Adam Speight
la source
0

J - 97 octets

Eh bien, l'approche la plus simple disponible. L'entrée est prise comme 111222333, où les nombres représentent des lignes. Lisez de gauche à droite. Le joueur est xet l'ennemi l'est o. Les cases vides peuvent être n'importe quoi sauf xou o.

f=:(cat`lose>@{~'ooo'&c)`('win'"_)@.('xxx'&c=:+./@(r,(r|:),((r=:-:"1)(0 4 8&{,:2 4 6&{)@,))3 3&$)

Exemples: (NB. Est un commentaire)

   f 'xoxxoxxox' NB. Victory from first and last column.
win
   f 'oxxxooxxx' NB. Victory from last row.
win
   f 'ooxxoxxxo' NB. The example case, lost to a diagonal.
lose
   f 'xxooxxxoo' NB. Nobody won.
cat
   f 'xoo xx ox' NB. Victory from diagonal.
win

Code non golfé une explication

row   =: -:"1                        Checks if victory can be achieved from any row.
col   =: -:"1 |:                     Checks if victory can be achieved from any column.
diag  =: -:"1 (0 4 8&{ ,: 2 4 6&{)@, Checks if victory can be achieved from diagonals.
check =: +./@(row,col,diag) 3 3&$    Checks all of the above and OR's them.

f     =: (cat`lose >@{~ 'ooo'&check)`('win'"_)@.('xxx'&check)
Check if you have won ........................@.('xxx'&check)
 If yes, return 'win' .............. ('win'"_)
 If not                   (cat`lose >@{~ 'ooo'&check)
  Check if enemy won ................... 'ooo'&check
   If yes, return 'lose'   ---`lose >@{~
   If not, return 'cat'    cat`---- >@{~
seequ
la source
0

Python 2, 120 octets

b=0b101001110
l=[448,56,7,292,146,73,273,84]
print(['Win'for w in l if w&b==w]+['Lose'for w in l if w&~b==w]+['Cat'])[0]

Ou Python, à 115 octets du shell Python (2 ou 3):

b=0b101001110;l=[448,56,7,292,146,73,273,84];(['Win'for w in l if w&b==w]+['Lose'for w in l if w&~b==w]+['Cat'])[0]

La variable board est définie au format binaire décrit dans la question: 1pour X, 0pour O, de gauche à droite, de haut en bas. Dans ce cas,101001110 représente

XOX
OOX
XXO

Ce qui conduit à une sortie: Cat

Cees Timmerman
la source
Quel est le format d'entrée?
seequ
0

Python ( 73 62 caractères)

L'entrée est composée de quatre chaînes minuscules représentant quatre vues distinctes de la même carte, toutes concaténées en une seule chaîne: par ligne, par colonne, diagonale droite, diagonale gauche.

MISE À JOUR

Merci à theRare de l'avoir signalé avec un bon contre-exemple! Chaque vue du tableau, ainsi que chaque segment (ligne ou colonne) d'un tableau doit être séparé par un caractère qui n'est ni un "x" ni un "o" afin que la structure du tableau soit préservée même après concaténation. Les bordures autour de chaque vue du tableau seront des crochets ("[" et "]"), et le séparateur entre les lignes / colonnes sera un caractère "|".

Cela rend l'algorithme simple - recherchez simplement "xxx" ou "ooo" pour un gain ou une perte, respectivement. Sinon c'est une cravate (chat).

Par exemple le tableau (lecture de gauche à droite, de haut en bas) ...

X | X | X X | O | X O | X | O

... est représenté par "[xxx | xox | oxo]" (par lignes) + "[xxo | xox | xxo]" (par colonnes) + "[xoo]" (diag à droite) + [xoo] "(à gauche diag) = "[xxx | xox | oxo] [xxo | xox | xxo] [xoo] [xoo]".

Cette instruction Python affiche le résultat du jeu en fonction de la variable s en entrée:

print 'win' if 'xxx' in s else 'lose' if 'ooo' in s else 'cat'
bob
la source
Est-ce que cela fonctionne pour la planche OXX XOO XOX(ce devrait être un chat)?
seequ
Non ... non, ce n'est pas le cas. Bonne prise! Je suppose que ma solution était un peu trop simple ... Oups!
bob
Je ne peux pas dire que ce type de solution ne m'a pas traversé l'esprit. :)
seequ
0

Haskell (69 caractères)

i x=take 4$(x>>=(\y->case y of{'7'->"win";'0'->"lose";_->""}))++"cat"

Cela prend la même entrée que celle décrite par cette réponse . Plus précisément, l'entrée est de 8 valeurs octales, décrivant la valeur binaire de chaque ligne, colonne et diagonale. Le code fait que chaque instance de 7 "gagne", chaque instance de 0 "perd" et supprime tout le reste. Ensuite, il ajoute "chat" à la fin et prend les 4 premiers caractères du résultat.

Il y aura 4 réponses possibles: "perdre", "chat", "gagner" suivi d'un 'l' et "gagner" suivi d'un 'c', ce que les règles n'interdisent pas :)

Exemple d'utilisation:

i "65153806" --outputs "lose"
TheBrownMotie
la source
0

J: 83

(;:'lose cat win'){::~>:*(-&(+/@:(*./"1)@;@(;((<0 1)&|:&.>@(;|.)(,<)|:)))-.)3 3$'x'=

Utilisation: ajoutez simplement une chaîne de x et o et regardez le travail magique. par exemple. «xxxoooxxx».

Le verbe intérieur (+/@:(*./"1)@;@(;((<0 1)&|:&.>@(;|.)(,<)|:))) essentiellement la matrice binaire d'origine, avec la transposition encadrée avec les 2 diagonales. Ces résultats sont rasés ensemble; des sommes de ligne sont prises pour déterminer les victoires, puis additionnées. plus loin, j'appellerai ce verbe Inner.

Pour trouver le gagnant, la différence des scores entre les matrices binaires normales et inversées est prise par le crochet (-&Inner -.) .

Le reste du code effectue simplement les sorties et sélectionne la bonne.

jpjacobs
la source
0

JavaScript, 133 , 114 caractères

r = '/(1){3}|(1.{3}){2}1|(1.{4}){2}1|(1\|.1.\|1)/';alert(i.match(r)?'WIN':i.match(r.replace(/1/g,0))?'LOSS':'CAT')

L'entrée iest une chaîne simple avec des délimiteurs pour les lignes, c'est-à-dire100|001|100

Edit: mis à jour ma méthode pour remplacer les 1 dans l'expression régulière par des zéros pour vérifier le cas de perte.

thomaux
la source
Vous pouvez supprimer les espaces autour =et les guillemets autour du littéral d'expression régulière. En outre, 1...est un caractère plus court que 1.{3}.
nyuszika7h
1
r.test(i)est également un caractère plus court que i.match(r).
nyuszika7h
0

J - 56 (26?) Char

L'entrée reçoit une matrice 3x3 de neuf caractères, car J peut le prendre en charge en tant que type de données, LOL.

(win`lose`cat{::~xxx`ooo<./@i.<"1,<"1@|:,2 7{</.,</.@|.)

Exemples:

   NB. 4 equivalent ways to input the example board
   (3 3 $ 'xxoxoxoox') ; (_3 ]\ 'xxoxoxoox') ; ('xxo','xox',:'oox') ; (];._1 '|xxo|xox|oox')
+---+---+---+---+
|xxo|xxo|xxo|xxo|
|xox|xox|xox|xox|
|oox|oox|oox|oox|
+---+---+---+---+
   (win`lose`cat{::~xxx`ooo<./@i.<"1,<"1@|:,2 7{</.,</.@|.) 3 3 $ 'xxoxoxoox'
lose
   wlc =: (win`lose`cat{::~xxx`ooo<./@i.<"1,<"1@|:,2 7{</.,</.@|.)
   wlc (3 3 $ 'xoxoxooxo')
cat
   wlc (3 3 $ 'xxxoooxxx')
win

Si nous sommes autorisés à encoder Golfscriptish des chiffres octaux représentant de manière redondante l'état de chaque ligne, colonne et diagonale, alors ce ne sont que 26 caractères:

   win`lose`cat{::~7 0<./@i.] 6 5 1 6 4 3 5 0
lose
   f=:win`lose`cat{::~7 0<./@i.]
   f  7 0 7 5 5 5 5 5
win
algorithmshark
la source
0

T-SQL (2012), 110

select max(iif(@&m=0,'lose',iif(@&m=m,'win','cat')))from(VALUES(292),(146),(73),(448),(56),(7),(273),(84))z(m)

L'entrée est un nombre hexadécimal. C'est à peu près une traduction de la solution ruby ​​en T-SQL assez agréable et soignée.

Michael B
la source
0

Javascript 1.6, 71 caractères

Je suppose que l'entrée est un tableau gamequi contient chaque ligne, chaque colonne et chaque diag comme une chaîne de 3 caractères. Semblable à la réponse de bob , mais il vient dans un tableau, pas comme une chaîne concaténée.

alert(game.indexOf("xxx")>=0?"win":game.indexOf("ooo")>=0?"lose":"cat")

EDIT @ nyuszika7h 's comment (67 caractères)

alert(~game.indexOf("xxx")?"win":~game.indexOf("ooo")?"lose":"cat")
JNF
la source
Vous pouvez utiliser à la ~game.indexOf("xxx")place de game.indexOf("xxx")>=0, même pour l'autre.
nyuszika7h
0

Java 7, 260 octets

String c(int[]s){int a[]=new int[8],x=0,y;for(;x<3;x++){for(y=0;y<3;a[x]+=s[x*3+y++]);for(y=0;y<3;a[x+3]+=s[y++%3]);}for(x=0;x<9;y=s[x],a[6]+=x%4<1?y:0;a[7]+=x%2<1&x>0&x++<8?y:0);x=0;for(int i:a)if(i>2)return"win";for(int i:a)if(i<1)return"loose";return"cat";}

Cas non testés et testés:

Essayez-le ici.

class M{
  static String c(int[] s){
    int a[] = new int[8],
        x = 0,
        y;
    for(; x < 3; x++){
      for(y = 0; y < 3; a[x] += s[x * 3 + y++]);
      for (y = 0; y < 3; a[x + 3] += s[y++ % 3]);
    }
    for(x = 0; x < 9; y = s[x],
                      a[6] += x % 4 < 1
                               ? y
                               : 0,
                      a[7] += x % 2 < 1 & x > 0 & x++ < 8
                               ? y
                               : 0);
    x = 0;
    for(int i : a){
      if(i > 2){
        return "win";
      }
    }
    for(int i : a){
      if(i < 1){
        return "loose";
      }
    }
    return "cat";
  }

  public static void main(String[] a){
    /*  xxo
        xox
        oox  */
    System.out.println(c(new int[]{ 1, 1, 0, 1, 0, 1, 0, 0, 1 }));
    /*  xxx
        ooo
        xxx  */
    System.out.println(c(new int[]{ 1, 1, 1, 0, 0, 0, 1, 1, 1 }));
    /*  xxo
        oox
        xox  */
    System.out.println(c(new int[]{ 1, 1, 0, 0, 0, 1, 1, 0, 1 }));
  }
}

Production:

loose
win
cat
Kevin Cruijssen
la source
0

APL (NARS), 69 caractères, 138 octets

{w←3 3⍴⍵⋄x←(+/1 1⍉⊖w),(+/1 1⍉w),(+⌿w),+/w⋄3∊x:'win'⋄0∊x:'lose'⋄'cat'}

L'entrée doit être une matrice 3x3 ou un tableau linéaire de 9 éléments qui ne peuvent être que 1 (pour X) et 0 (pour O), le résultat sera "chat" si personne ne gagne, "perd" si O gagne, "gagne "si X gagne. Il n'y a aucune vérification pour une carte non valide ou une entrée est un tableau a moins de 9 éléments ou plus ou vérifiez chaque élément <2.

Comme commentaire: il convertirait l'entrée dans une matrice 3x3 et construirait un tableau nommé "x" où les éléments sont la somme de chaque colonne de ligne et diagonale.

Certains tests voient l'exemple montré par d'autres:

  f←{w←3 3⍴⍵⋄x←(+/1 1⍉⊖w),(+/1 1⍉w),(+⌿w),+/w⋄3∊x:'win'⋄0∊x:'lose'⋄'cat'}
  f 1 2 3
win
  f 0 0 0
lose
  f 1 0 1  1 0 1  1 0 1
win
  f 0 1 1  1 0 0  1 1 1
win
  f 0 0 1  1 0 1  1 1 0
lose
  f 1 1 0  0 1 1  1 0 0
cat
  f 1 1 0  0 1 0  0 0 1
win
  f 1 1 0  1 0 1  0 0 1
lose
RosLuP
la source