Jouez à Connect 4!

20

Écrivez un programme pour jouer au jeu de Connect 4 . On vous donne l'état du plateau en entrée et vous devez décider dans quelle colonne placer votre pièce pour obtenir 4 d'affilée (horizontalement, verticalement ou en diagonale) ou empêcher votre adversaire de faire de même.

Le plateau est un tableau 6x7, où chaque cellule peut être vide (''), contenir votre pièce ('X') ou la pièce de votre adversaire ('O'). Un exemple de tableau:

O      
XX    X
XOX  OO
XOO OXO
OXXOXXO
XOXOXOX

Vous voudriez jouer dans la colonne 3 (les colonnes sont 0-6, numérotées à partir de la gauche) pour la victoire diagonale. Vous produisez donc:

3

Votre code doit générer un numéro de colonne et doit répondre aux critères suivants:

  1. Vous ne pouvez pas jouer dans une colonne qui contient déjà 6 pièces.
  2. S'il y a au moins un coup gagnant, vous devez jouer l'un d'eux.
  3. Si vous pouvez empêcher votre adversaire de gagner lors de son prochain coup, vous devez le faire.

Notez qu'un jeu optimal n'est pas nécessaire, seulement que vous remportez une victoire immédiate ou empêchez la victoire immédiate de votre adversaire. Si votre adversaire a plus d'une façon de gagner, vous ne devez bloquer aucune d'entre elles.

On vous donne la carte sur l'entrée standard et vous devez imprimer un numéro de colonne dans lequel vous voulez jouer sur la sortie standard. Le plateau est garanti d'être bien formé (pas de trous, au moins un coup possible) et de ne pas déjà avoir de victoire pour aucun des joueurs.

Le code le plus court gagne.

Exemple 1

      X
      O
      X
      O
 OOO  X
 XXX  O

Vous devez jouer soit la colonne 0 ou 4 pour la victoire.

Exemple 2

      X
X     X
O     O
XOX  XO
XXO XOX
XXO XXO

Vous devez jouer la colonne 3 pour bloquer la victoire immédiate de votre adversaire.

Exemple 3

X      
XO     
OX    O
XO   XX
XXO OOO
OOO XXO

Vous ne pouvez pas gagner ou empêcher votre adversaire de gagner, vous pouvez donc jouer n'importe quelle colonne 1-6 (0 est plein).

Exemple 4

X      
O      
X      
OOO    
XOX    
OXOX   

Vous ne pouvez pas jouer dans la colonne 3, car cela permet à votre adversaire de gagner immédiatement. Vous pouvez jouer dans les colonnes 1-2 ou 4-6.

Keith Randall
la source

Réponses:

9

C, 234 286 256 caractères

Correction pour résoudre correctement le problème, en vérifiant les mouvements gagnants de l'adversaire après chaque tentative de mouvement.

Ce code est très sensible au format du fichier d'entrée - chaque ligne doit contenir 7 caractères + nouvelle ligne.
La carte est traitée comme une matrice 8x8, plutôt que 7x6. La 8e colonne contient les sauts de ligne et les 2 lignes supplémentaires contiennent des zéros, de sorte qu'elles n'interfèrent pas avec la solution. Ils aident réellement - Lorsque vous vous déplacez à droite de la colonne la plus à droite, vous accédez à la colonne de nouvelle ligne, qui sert de vérification des limites.

wvérifie une position pour une opportunité de gagner ou de bloquer. qdevrait être la cellule à vérifier. Il utilise reursion pour parcourir 4 directions (commence par 9,8,7, puis plusieurs fois 1).
Cvérifie une séquence de caractères identiques commençant qdans la direction d, à la fois dans les deux sens . Il renvoie la somme des deux séquences (sans compter la position de départ), donc s'il renvoie 3, il y a une ligne de 4.

char B[99],q;
C(i,d){
    return B[d*i+++q]-B[q]?d>0?C(1,-d):0:1+C(i,d);
}
w(x){
    return x&&C(1,x>6?x:1)>2|w(x-1);
}
t(l,c,r,v){
    for(;c--;)B[q=c]&32&B[c+8]-32?r=w(9,B[c]=l)?v=c:v||r*t(79,l,0,1)?r:c,B[c]=32:0;
    return r;
}
main(){
    putchar(48+t(88,16+read(0,B+16,48),0,0)%8);
}
ugoren
la source
5

Python 2.x - 594 591 576 557 523 459 458 433 octets

C'est le meilleur que j'ai réalisé jusqu'à présent. Je suppose qu'il est difficile de battre C. Défi impressionnant, je dois dire.

r=range
f=[]
exec'f+=list(raw_input());'*6
def n(p):
 o,b,a,k=[],1,'O',lambda q:any([o[i:i+4]==list(q)*4for o in(f[x-x%7:],f[x%7::7])for i in r(3)]+[all(q==f[7*(y+u*i)+z+i]for i in r(4))for u,z,v,c in((1,0,3,4),(-1,3,6,3))for y in r(z,v)for z in r(c)])
 for x in r(42):
    if x>34<a>f[x]or x<35and f[x+7]>'0'>f[x]:f[x]=p;z=k(p)*b;o=z*[x]+o+[x]*(a==p or n(a)[1]);b-=z;f[x]=' '
 return o[0]%7,b
a,b,c,d=n('X')+n('O')
print(a,(c,a)[d])[b]

La ligne if (ligne 7) a une indentation d'un onglet. SE n'aime pas les onglets.

seequ
la source
2
Je passe beaucoup trop de temps à les affiner. En outre, la version 458 octets ne fonctionnait pas correctement pour l'exemple # 4. Retirez 25 octets et c'est le cas. La magie.
seequ