Connect Four Validator

20

introduction

Connect Four est un jeu où vous essayez d'en obtenir quatre de suite: horizontalement, verticalement ou en diagonale. Dans ce code de golf, nous allons essayer de trouver qui a gagné, avec un plateau de jeu. Il y aura toujours un gagnant et un seul gagnant.


Tâche

Étant donné un tableau Connect Four, déterminez qui est le gagnant: Xou Y. Il y aura toujours un gagnant et un seul gagnant. La taille du plateau sera toujours de 6 par 7 comme la façon dont le plateau de jeu est dans l'image.

Étant donné un tableau, le tableau suivant, dans ce cas, Xest rouge et Ybleu:

entrez la description de l'image ici

Votre contribution serait:

OOOOOOO
OOOOOOO
OOOOOOO
OOOOXOO
OOOXXOO
OOXYYYY

Vous pouvez séparer les lignes du jeu par un caractère de nouvelle ligne (comme ci-dessus), pas de caractère de division, diviser les lignes en un tableau ou une liste, ou vous pouvez saisir une matrice de caractères.

Sortie correcte pour cet exemple:

Y

Y en a quatre de suite; donc, Y est le gagnant. Donc, nous sortons Y.


Cas de test

Contribution:

OOOOOOO
OOOOOOO
OOOOOOO
OOOOOOO
OOYYOOO
OYXXXXO

Production:

X

Contribution:

OOOOOOO
OOOOOOO
OOOOOOO
XXXXOOO
YXYYOOO
YXYYXYX

Production:

X

Contribution:

YXYYXOO
XYXXYOO
XXXYYOO
YYYXXOO
XXYYYYO
XXYYXXO

Production:

Y

Contribution:

OOOOOOO
OOOOOOO
OYOOOOO
OOYOOOO
OOOYOOO
OOOOYOO

Production:

Y

Contribution:

OOOOOOO
OOOOOOO
OYOOOOX
OOYOOOX
OOOXOOX
OXOXYOX

Production:

X

Notation

Le moins d'octets gagne!

Neil
la source
C'est le défi parfait pour PMA / Snails codegolf.stackexchange.com/questions/47311/…
Jerry Jeremiah
2
Pouvons-nous supposer que le gagnant aura toujours un jeton de plus que le perdant?
accro aux mathématiques
1
@mathjunkie J'avais tort, vous ne pouvez pas supposer cela.
Neil
3
@nfnneil la sortie doit-elle être X ou Y ou pouvons-nous choisir deux autres sorties cohérentes pour indiquer le gagnant?
Martin Ender
1
Pouvons-nous choisir d'utiliser d'autres caractères comme entrée? Ou pour entrer une matrice numérique?
Luis Mendo

Réponses:

2

Gelée , 19 octets

UŒD;ŒD;Z;ṡ€4;/ṢEÞṪṪ

Essayez-le en ligne!

Le cœur de cette réponse est copié de ma réponse à cette question très similaire .

Explication

UŒD;ŒD;Z;ṡ€4;/ṢEÞṪṪ
   ;  ; ;             Append {the input} and the following three values:
UŒD                     the antidiagonals of {the input};
    ŒD                  the diagonals of {the input};
       Z                the transposed {input}.
         ṡ 4          Find all length-4 substrings
          €             of each subarray within that.
            ;/        Flatten one level.
                Þ     Sort, with the following sort order:
               E        If all elements are the same, sort later.
              Ṣ         Tiebreak via lexicographical order.
                 ṪṪ   Take the last element of the last element.

Assez simple: nous prenons toutes les lignes, colonnes, diagonales et antidiagonales (comme dans le validateur n-reines), puis prenons toutes les sous-chaînes de longueur 4 de celles-ci, puis les trions de telle sorte que la ligne gagnante de 4 trie la fin. (Nous avons besoin du bris d'égalité au cas où il y en aurait un OOOOen plus du XXXXou YYYY.) Prenez le dernier élément du dernier élément, et ce sera Xou Yselon les besoins.


la source
6

Rétine, 51 48 octets

Merci à Martin Ender pour avoir économisé 3 octets

M`X((.{6}X){3}|(.{8}X){3}|(.{7}X){3}|XXX)
T`d`YX

Essayez-le en ligne!

Prend l'entrée comme une liste de lignes séparées par des virgules

accro aux mathématiques
la source
Vous pouvez économiser quelques octets en utilisant une étape de correspondance et en la raccourcissant (.{7}X){3}|XXXà (.{7}X|X)\4\4: tio.run/nexus/retina#fc4xCsMwDAXQPfcI2GC6NDS5QaeipcP/…
Martin Ender
1
@MartinEnder Je ne vois pas comment vous pouvez utiliser \4- vous voulez répéter l'effet de la .{7}, et non la chaîne correspondante. (Et les groupes d'équilibrage seraient probablement beaucoup trop longs.)
Neil
1
@Neil oh ouais, peu importe, je ne pensais pas qu'il y avait d'autres cellules OXY que la correspondance dans la grille. l'utilisation de la phase de correspondance économise alors 3 octets.
Martin Ender
5

Javascript (ES6), 54 55

Modifier 1 octet enregistré grâce à @Arnauld

Je vérifie simplement si X est le gagnant, car il y aura toujours un gagnant et un seul gagnant

L'entrée est une chaîne avec n'importe quel séparateur, comme dans la réponse de @ Arnauld

F=    
b=>'YX'[+[0,6,7,8].some(x=>b.match(`X(.{${x}}X){3}`))]

;['OOOOOOO OOOOOOO OOXOOOO OOXOOOO OOXOOOO OOXOYYY'
 ,'OOOOOOO OOOOOOO OOXOOOO OOYXOOO OOYOXOO OOYYOXY'
 ,'OOOOOOO,OOOOOOO,OOOOOOO,OOOOOOO,OOYYOOO,OYXXXXO'
 ,'OOOOOOO,OOOOOOO,OOOOOOO,XXXXOOO,YXYYOOO,YXYYXYX'
 ,'YXYYXOO,XYXXYOO,XXXYYOO,YYYXXOO,XXYYYYO,XXYYXXO']
.forEach(s => console.log(s,F(s)))

edc65
la source
@Arnauld à droite, merci
edc65
4

Gelée , 25 22 octets

ŒgL⁼¥Ðf
;UŒD€;Z;$ç€4FṀ

Prend une liste de chaînes (ou une liste de listes de caractères) formées de X, Yet O(fonctionnerait également avec des remplacements tels que l'espace a un ordinal inférieur à celui des deux compteurs).

Essayez-le en ligne! ou exécutez une version augmentée qui prend une chaîne multiligne.

Comment?

ŒgL⁼¥Ðf - Link 1, runs of given length: list A, length B  e.g. "XYYYXXO", 4
Œg      - group runs of equal elements of A                     ["X","YYY","XX","O"]
     Ðf - filter keep:
    ¥   -     last two links as a dyad:
  L     -         length                                         1   3     2    1
   ⁼    -         equal to B?         (none kept in this case->) 0   0     0    0

;UŒD€;Z;$ç€4FṀ - Main link: list of list of chars (or list of stings) I
 U             - reverse each row of I
;              - I concatenated with that
  ŒD€          - positive diagonals of €ach (positive and negative diagonals)
        $      - last two links as a monad:
      Z        -     transpose of I (i.e. the columns)
       ;       -     concatenated with I (columns + rows)
     ;         - concatenate (all the required directional slices)
         ç€4   - call the last link (1) as a dyad for €ach with right argument = 4
            F  - flatten the result
             Ṁ - take the maximum ('Y'>'X'>'O') - this has the bonus effect of returning:
                               'Y' or 'X' for a winning board; and
                               'O' or '' for a (valid) game in progress.
Jonathan Allan
la source
4

JavaScript (ES6), 77 76 69 octets

7 octets enregistrés grâce à Neil

Prend l'entrée comme une chaîne séparée par quelque chose , où quelque chose est essentiellement n'importe quel caractère.

b=>[...'XXXXYYYY'].find((c,i)=>b.match(`(${c}.{${(i%4+6)%9}}){3}`+c))

Cas de test

Arnauld
la source
Pourquoi ne pas utiliser b.match()? Devrait économiser sur l' RegExpappel.
Neil
@Neil J'ai totalement oublié que je match()faisais une conversion implicite vers RegExp. Merci!
Arnauld
3

Python 2 , 143 octets

m=input()
u=[r[::-1]for r in m]
print"YX"[any(any('X'*4in''.join(t[i][j-i]for i in range(j+1))for j in range(6))for t in(m[::-1],m,u,u[::-1]))]

Prend une liste de chaînes ou une liste de liste de caractères. Codé en dur pour 6 lignes par 7 colonnes, comme le garantit la spécification.

Essayez-le en ligne!

Jonathan Allan
la source
2

PHP, 71 octets

echo preg_match('#X(XXX|(.{8}X){3}|(.{7}X){3}|(.{9}X){3})#',$argn)?X:Y;

Version en ligne

Jörg Hülsermann
la source
2

Python 2 , 201 143 129 128 107 octets

J'ai décidé d'ajouter horizontal, vertical et diagonal ensemble dans une liste, puis d'ajouter un incrément, puis de rechercher X pour les fois. Et puisqu'il y aura toujours un gagnant, je peux supposer que Y a gagné si X ne le fait pas. Ce code prend une matrice de toutes les différentes pièces et lieux vides.

lambda m:"YX"[any("X"*4in"".join(a)for a in zip(*m)+m+zip(*["0"*(7-i)+m[i]+"00"*i+m[i]for i in range(6)]))]

Essayez-le en ligne!

Crédits

Neil
la source
Il est parfaitement acceptable de répondre par lui-même.
Jonathan Allan
Sans regarder trop à elle, il semble y avoir des espaces blancs inutiles à: i:] for, i, r, r] foret 1 for.
Yytsi
@TuukkaX Merci pour l'entrée, mise à jour.
Neil
, Également *(len(m)-1)pourrait être *~-len(m). Comment ça fonctionne.
Yytsi
Le ] foret 1 forsont toujours là.
Yytsi
1

K (ngn / k) , 58 55 octets

{"XY"@|/&/'88<x ./:/:,/{x+/:/:+3+[4#1-+!3 3]\&4}'+!6 7}

Essayez-le en ligne!

{ } fonction avec argument x

+!6 7 toutes les paires possibles de 0..5 et 0..6

{ }' pour chacun d'eux

4#1-+!3 3 sont 4 des 8 directions ortho-diagonales: (1 1;1 0;1 -1;0 1)

3+[ ]\&4commencez par une liste de quatre zéros ( &4) et faites 3 étapes dans chacune des directions

x+/:/: partir de chaque position possible et faire les pas dans chaque direction possible

,/enchaîner. à ce stade, nous avons une matrice de 4 listes de paires de coordonnées, certaines s'étendant au-delà du plateau

x ./:/: rechercher les cellules correspondantes de x

88<lesquels sont "Y"-s? (88 est le code ascii de "X")

&/'quelles 4 listes se composent uniquement de "Y"-s? (et-réduire-chacun)

|/en existe-t-il au moins un? (ou-réduire)

"XY"@si faux retour "X", si vrai retour"Y"

ngn
la source
1

Zsh , 207 ... 159 octets

Historique des versions: 4 itérations pour ~ 25 octets la première semaine; puis 3 itérations supplémentaires pour ~ 25 octets 6 mois plus tard.

t(){a=($^a-$^@_);for s l (${w:^^argv})s+=$l&&for ((i=0;i++<$#s;))a[i]+=$s[i];}
w=(+)
t $@
for s;w[++j]=${(l:j:)}_
t $@
t ${(Oa)@}
[[ $a = *XXXX* ]]&&<<<X||<<<Y

( premier ) ( deuxième ) ( troisième ) ( quatrième ) ( cinquième ) ( sixième ) Essayez-le en ligne!

Dans le pied de page, j'imprime à la fois la carte d'entrée et le tableau que nous construisons à partir de stderr. Faites défiler vers le bas pour déboguer pour les voir. Le tableau que nous construisons est beaucoup plus long maintenant, car il existe un tproduit cartésien avec une carte d'entrée à chaque appel. (Hé, cela a raccourci le code de quelques octets.)

Il y a beaucoup de choses à couvrir ici, j'ai donc déplacé les commentaires (sixième édition) dans un résumé annoté .

(tl; dr: concaténer les transpositions du tableau d'origine, mais assurez-vous de les garder séparées)

GammaFunction
la source