Foros del Web » Programación para mayores de 30 ;) » C/C++ »

[SOLUCIONADO] Juego 4 en raya

Estas en el tema de Juego 4 en raya en el foro de C/C++ en Foros del Web. Hola a todos estoy haciendo el juego del 4 en raya y a la hora de sacar el ganador no me funciona bien porque creo ...
  #1 (permalink)  
Antiguo 06/06/2014, 01:12
 
Fecha de Ingreso: junio-2014
Ubicación: San Vicente del Raspeig
Mensajes: 9
Antigüedad: 10 años, 5 meses
Puntos: 0
Pregunta Juego 4 en raya


Hola a todos estoy haciendo el juego del 4 en raya y a la hora de sacar el ganador no me funciona bien porque creo que al estar sumando filas y columnas me estoy saliendo de la matriz de enteros. Estoy usando Qt designer C++ para hacer la interfaz del juego. Si alguien puede ayudarme con el método Ganado(); para sacar las horizontales, verticales y diagonales le estaría muy agradecido. Adjunto el enunciado y el programa por partes ya que esta dividido en ficheros:

ENUNCIADO:
En este ejercicio vamos a implementar el conocido juego de las 4 en raya o conecta 4. El programa arrancará con un panel de 6x7 vacío, informando que es el turno de las piezas rojas. Cuando tire el primer jugador (pinchando con el ratón en alguno de los botones azules) se colocará la ficha en la columna correspondiente y dará el turno al segundo jugador (piezas amarillas).
En cualquier momento se podrá reiniciar la partida (segundo botón), salir, o mostrar el Acerca de (About) de la aplicación. El programa controlará que no se tira sobre una columna llena y también comprobará tras cada jugada si ha ganado alguno de los jugadores o han quedado empates (Figura 2). Cuando algún jugador gane o queden en tablas informaremos al usuario y la partida se reiniciará (borraremos el tablero y será el turno de las rojas de nuevo).

CÓDIGO:
<mainwindow.h>
-----------------------------------------------------------------------------------------------
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPushButton>

#include<iostream>
using namespace std;

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();

private slots:

void on_actionSalir_triggered();

void on_actionAcerca_de_triggered();

void on_pushButton_7_clicked();

void on_pushButton_9_clicked();

void on_pushButton_11_clicked();

void on_pushButton_13_clicked();

void on_pushButton_15_clicked();

void on_pushButton_17_clicked();

void on_pushButton_19_clicked();

void on_actionNuevo_Juego_triggered();

void BotonPulsado(int columna);

void Ganado(int fila,int columna,int ficha);

private:
//declaracion de los atributos necesarios para nuestro codigo.
Ui::MainWindow *ui;
QPushButton *M[6][7];
int V[7];
int Mint[6][7];
bool turno;
bool ganadorojas;
bool ganadoamar;
};

#endif // MAINWINDOW_H
----------------------------------------------------------------------------------------------
<main.cpp>
#include "mainwindow.h"
#include <QApplication>


int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();

return a.exec();
}
---------------------------------------------------------------------------------------------
<mainwindow.cpp>
#include "mainwindow.h"
#include "ui_mainwindow.h"

//librerias para las distinas opciones
#include <QMessageBox>
#include <QPushButton>
#include <QIcon>
#include <QPixmap>


//Constructor de la ventana principal
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
//Inicializacion de la ventana.
ui->setupUi(this);

//Asignacion de los botones a las distintas posiciones de la matriz.
M[0][0] = ui->pushButton_8;
M[0][1] = ui->pushButton_10;
M[0][2] = ui->pushButton_12;
M[0][3] = ui->pushButton_14;
M[0][4] = ui->pushButton_16;
M[0][5] = ui->pushButton_18;
M[0][6] = ui->pushButton_20;
M[1][0] = ui->pushButton_21;
M[1][1] = ui->pushButton_22;
M[1][2] = ui->pushButton_23;
M[1][3] = ui->pushButton_24;
M[1][4] = ui->pushButton_25;
M[1][5] = ui->pushButton_26;
M[1][6] = ui->pushButton_27;
M[2][0] = ui->pushButton_28;
M[2][1] = ui->pushButton_29;
M[2][2] = ui->pushButton_30;
M[2][3] = ui->pushButton_31;
M[2][4] = ui->pushButton_32;
M[2][5] = ui->pushButton_33;
M[2][6] = ui->pushButton_34;
M[3][0] = ui->pushButton_35;
M[3][1] = ui->pushButton_36;
M[3][2] = ui->pushButton_37;
M[3][3] = ui->pushButton_38;
M[3][4] = ui->pushButton_39;
M[3][5] = ui->pushButton_40;
M[3][6] = ui->pushButton_41;
M[4][0] = ui->pushButton_42;
M[4][1] = ui->pushButton_43;
M[4][2] = ui->pushButton_44;
M[4][3] = ui->pushButton_45;
M[4][4] = ui->pushButton_46;
M[4][5] = ui->pushButton_47;
M[4][6] = ui->pushButton_48;
M[5][0] = ui->pushButton_49;
M[5][1] = ui->pushButton_50;
M[5][2] = ui->pushButton_51;
M[5][3] = ui->pushButton_52;
M[5][4] = ui->pushButton_53;
M[5][5] = ui->pushButton_54;
M[5][6] = ui->pushButton_55;

for(int i=0;i<7;i++){
V=0;
}
for(int j=0;j<6;j++){
for(int k=0;k<7;k++){
Mint[j][k]=0;
}
}
turno=true;
ganadorojas=false;
ganadoamar=false;
}
//Destructor
MainWindow::~MainWindow()
{
delete ui;
}
//funcion salir triggered
void MainWindow::on_actionSalir_triggered()
{
close();
}
//funcion acerca de triggered
void MainWindow::on_actionAcerca_de_triggered()
{
QMessageBox::information(this,"Acerca del Juego","Realizado por Alvaro Garrido Tafalla y Jorge Medina Carbonell","Aceptar");
}
//funcion reiniciar juego triggered
void MainWindow::on_actionNuevo_Juego_triggered()
{
for(int i=0;i<6;i++){
for(int j=0;j<7;j++){
M[j]->setIcon(QIcon(":/Iconos/Material ejercicio 1/circle_grey.png"));
Mint[j]=0;
}
}
for(int i=0;i<7;i++){
V=0;
}
turno=true;
ganadorojas=false;
ganadoamar=false;
ui->label->setText("Turno de las rojas");
}
//Funciones clicked de cada boton del panel, que llaman a la funcion BotonPulsado
void MainWindow::on_pushButton_7_clicked()
{
BotonPulsado(0);
}
void MainWindow::on_pushButton_9_clicked()
{
BotonPulsado(1);
}
void MainWindow::on_pushButton_11_clicked()
{
BotonPulsado(2);
}
void MainWindow::on_pushButton_13_clicked()
{
BotonPulsado(3);
}
void MainWindow::on_pushButton_15_clicked()
{
BotonPulsado(4);
}
void MainWindow::on_pushButton_17_clicked()
{
BotonPulsado(5);
}
void MainWindow::on_pushButton_19_clicked()
{
BotonPulsado(6);
}
//funcion BotonPulsado que permite cambir el icono de los botones.
void MainWindow::BotonPulsado(int columna){

if(V[columna]<6){//comprueba que no se tira sobre una columna llena
int pos=5-V[columna];
V[columna]=V[columna]+1;
if(turno==true){
M[pos][columna]->setIcon(QIcon(":/Iconos/Material ejercicio 1/circle_red.png"));
Mint[pos][columna]=1;
turno=false;
ui->label->setText("Turno de las amarillas");
Ganado(pos,columna,1);
}else{
M[pos][columna]->setIcon(QIcon(":/Iconos/Material ejercicio 1/circle_yellow.png"));
Mint[pos][columna]=2;
turno=true;
ui->label->setText("Turno de las rojas");
Ganado(pos,columna,2);
}
}
}
//Ganado
void MainWindow::Ganado(int fila,int columna,int ficha){


//horizontales
int cont=1;
if(Mint[fila][columna-1]==ficha || Mint[fila][columna+1]==ficha){
cont++;
if(Mint[fila][columna-2]==ficha || Mint[fila][columna+2]==ficha){
cont++;
if(Mint[fila][columna-3]==ficha || Mint[fila][columna+3]==ficha){
cont++;
if(ficha==1 && cont==4){
ganadorojas=true;
}else{
ganadoamar=true;
}
}
}
}
//verticales
if(Mint[fila-1][columna]==ficha || Mint[fila+1][columna]==ficha){
if(Mint[fila-2][columna]==ficha || Mint[fila+2][columna]==ficha){
if(Mint[fila-3][columna]==ficha || Mint[fila+3][columna]==ficha){
if(ficha==1){
ganadorojas=true;
}else{
ganadoamar=true;
}
}
}
}
if(ganadorojas==true ){
QMessageBox::information(this,"Fin de juego","Ganan las Rojas","OK");
on_actionNuevo_Juego_triggered();
}
if(ganadoamar==true){
QMessageBox::information(this,"Fin de juego","Ganan las Amarillas","OK");
on_actionNuevo_Juego_triggered();
}
}
-----------------------------------------------------------------------------------------------
  #2 (permalink)  
Antiguo 06/06/2014, 03:54
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 14 años, 1 mes
Puntos: 10
Respuesta: Juego 4 en raya

Hola:

Según lo que tu mismo dices, tiene pinta de que éstas sentencias:
Código C++:
Ver original
  1. //Ganado
  2. void MainWindow::Ganado(int fila,int columna,int ficha){
  3.  
  4. //horizontales
  5. int cont=1;
  6. if(Mint[fila][columna-1]==ficha || Mint[fila][columna+1]==ficha){
  7. cont++;
  8. if(Mint[fila][columna-2]==ficha || Mint[fila][columna+2]==ficha){
  9. cont++;
  10. if(Mint[fila][columna-3]==ficha || Mint[fila][columna+3]==ficha){
  11. cont++;
  12. ..................................

pueden acceder a posiciones de memoria no deseadas, ya que si estas en la fila 0 y columna 0, cuando haces
Código C++:
Ver original
  1. if(Mint[fila][columna-1]==ficha || Mint[fila][columna+1]==ficha)
por ejemplo, estarías accediendo a Mint[0][-1]
Por lo que has de refinar las condiciones del recorrido para no salirse de los límites.
Igual cuando recorres las verticales

Pero no he mirado nada más, así que esto que digo puede ser que sí, o puede ser que haya algo más.

Por cierto, y ya por curiosidad, ¿podrías suministrar el fichero ui_mainwindow.h o el fichero *.ui generado por el Designer?

Saludos
  #3 (permalink)  
Antiguo 06/06/2014, 04:25
 
Fecha de Ingreso: junio-2014
Ubicación: San Vicente del Raspeig
Mensajes: 9
Antigüedad: 10 años, 5 meses
Puntos: 0
Respuesta: Juego 4 en raya


Si, quería subir la carpeta donde tengo todos los ficheros pero soy nuevo aquí y he estado buscando como adjuntar un .rar pero no se como hacerlo...
  #4 (permalink)  
Antiguo 06/06/2014, 05:15
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 14 años, 1 mes
Puntos: 10
Respuesta: Juego 4 en raya

Bueno, creo que sólo hace falta el ui_mainwindow.h o el *.ui para poder ejecutar tu programa.

Por otro lado releyendo el mensaje ya veo que lo que pides es cómo implementar la función Ganado() para que funcione y no se salga de los límites.

A ver si en pseudocódigo:

variables de partida:
int lineadecuatro =0;
//buscar horizontales
recorro el tablero por filas
fila 0:
Si columna 0 tiene mi ficha, incrementar variable lineadecuatro
Si la variable lineadecuatro==4 retornar true y salir de la función
si no es así, volver a poner lineadecuatro a 0, para no acumular "trues" no consecutivos
Seguir así con columna 1, columna 2, etc....
si la fila 0 no contenía ninguna poner lineadecuatro a 0 y repetir con la siguiente fila

//horizontales:
Sería lo mismo pero recorriendo el array en vertical

//diagonales
Aquí es menos automático.
Entiendo que hay que hacer el barrido de derecha-arriba, luego derecha-abajo, luego izquierda-arriba y luego izquierda-abajo

Para el primer caso (derecha-arriba)
Puedes partir de que no merece la pena leer hasta la fila 3 (la 4 del array) porque antes no hay posibilidad de 4 en raya, y que cuando llegues a la columna 4 tampoco por la misma cuestión
Y luego hay que ir probando por cada fila (o columna) y siguiendo la misma técnica, recorrer las casillas que tengan una fila menos y una columna mas.
Para el resto de recorridos, el planteamiento es parecido pero cambiando los límites de búsqueda y los incrementos/decrementos de fila/columna para que vayan en diagona izquierda/derecha arriba/abajo.

Bueno, y he hecho un poco de código.
Es un programa que crea un tablero. Lo he hecho con bool siendo false donde no hay ficha y true donde sí las hay.
He rellenado el tablero en los casos horizontales, verticales y uno de los casos de diagonal.
Creo que la búsqueda horizontal y vertical funcionan sin problemas.
La búsqueda diagonal, sólo está implementada en el caso de buscar en dirección derecha-superior. Además no la he comprobado mucho, así que no pongo la mano en el fuego por ella. Pero la idea es la que te comenté más arriba.
Código C++:
Ver original
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. const int FILAS=6;
  5. const int COLUMNAS=7;
  6. bool buscar (bool tablero[FILAS][COLUMNAS]);
  7. void inicializarTablero (bool tablero[FILAS][COLUMNAS]);
  8. int main()
  9. {
  10.  
  11.     bool tablero[FILAS][COLUMNAS];
  12.     inicializarTablero(tablero);
  13.  
  14.     //pongo una linea de 4 horizontal en la fila 3 COLUMNAS 3 a 6
  15.     for (int i=3; i<7; i++)
  16.         {
  17.             tablero[3][i]=true;
  18.         }
  19.  
  20.     //recorro el tablero buscando lineas
  21.     buscar (tablero);
  22.  
  23.     //pongo el tablero a 0 y pongo una linea vertical
  24.     inicializarTablero(tablero);
  25.     //pongo una linea de 4 vertical en la columna 3 FILAS 2 a 5
  26.     for (int i=2; i<6; i++)
  27.         {
  28.             tablero[i][3]=true;
  29.         }
  30.     //recorro el tablero buscando lineas
  31.     buscar(tablero);
  32.  
  33.     //pongo el tablero a 0 y pongo una diagonal en (3,0)-(2,1)-(1,2)-(0,3)
  34.     inicializarTablero(tablero);
  35.     tablero[3][0]=true;
  36.     tablero[2][1]=true;
  37.     tablero[1][2]=true;
  38.     tablero[0][3]=true;
  39.     //recorro el tablero buscando lineas
  40.     buscar(tablero);
  41.  
  42.  
  43.  
  44.  
  45.     return 0;
  46. }
  47.  
  48. bool buscar (bool tablero[FILAS][COLUMNAS])
  49. {
  50.     int lineadecuatro=0;
  51.     //busqueda horizontal
  52.     for (int i=0; i<FILAS; i++)
  53.         {
  54.             for (int j=0; j<COLUMNAS; j++)
  55.                 {
  56.                     if (tablero[i][j]==true)
  57.                         {
  58.                             lineadecuatro++;
  59.                             if (lineadecuatro==4)
  60.                                 {
  61.                                     cout<<"Encontrada combinación en fila "<<i<<" y columnas "<<j-3<<","<<j<<endl;
  62.                                     return true;
  63.                                 }
  64.                         }
  65.                     else
  66.                     {
  67.                         lineadecuatro=0;
  68.                     }
  69.                 }
  70.             lineadecuatro=0;
  71.         }
  72.     lineadecuatro=0;
  73.     //busqueda vertical
  74.     for (int i=0; i<FILAS; i++)
  75.         {
  76.             for (int j=0; j<COLUMNAS; j++)
  77.                 {
  78.                     if (tablero[j][i]==true)
  79.                         {
  80.                             lineadecuatro++;
  81.                             if (lineadecuatro==4)
  82.                                 {
  83.                                     cout<<"Encontrada combinación en columna "<<i<<" y filas "<<j-3<<","<<j<<endl;
  84.                                     return true;
  85.                                 }
  86.                         }
  87.                     else
  88.                     {
  89.                         lineadecuatro=0;
  90.                     }
  91.                 }
  92.             lineadecuatro=0;
  93.         }
  94.     lineadecuatro=0;
  95.     //diagonal
  96.     /********primer barrido diagonal hacia arriba****/
  97.     for (int j=0; j-COLUMNAS-3; j++)
  98.         {
  99.             for (int i=3; i<FILAS; i++)
  100.                 {
  101.                     int fila=i;
  102.                     int columna=j;
  103.                     while (fila>=0)
  104.                         {
  105.                             if (tablero[fila][columna]==true)
  106.                                 {
  107.                                     cout<<"True en: "<<fila<<" , "<<columna<<endl;
  108.                                     lineadecuatro++;
  109.                                     if (lineadecuatro==4)
  110.                                         {
  111.                                             cout<<"Encontrada diagonal"<<endl;
  112.                                             return true;
  113.                                         }
  114.                                 }
  115.                             fila--;
  116.                             columna++;
  117.                         }
  118.                     lineadecuatro=0;
  119.                 }
  120.             lineadecuatro=0;
  121.             /*****siguiente barrido, por ejemplo diagonal hacia abajo*****/
  122.         }
  123.  
  124.     //si llego hasta aqui es porque no había ninguna fila de 4
  125.     return false;
  126. }
  127.  
  128. void inicializarTablero (bool tablero[FILAS][COLUMNAS])
  129. {
  130.     for (int i=0; i<FILAS; i++)
  131.         {
  132.             for (int j=0; j<COLUMNAS; j++)
  133.                 {
  134.                     tablero[i][j]=false;
  135.                 }
  136.         }
  137. }

Creo que con una pocas adaptaciones lo puedes adaptar a tu función Ganado().
  #5 (permalink)  
Antiguo 06/06/2014, 08:40
 
Fecha de Ingreso: junio-2008
Ubicación: Seattle, USA
Mensajes: 733
Antigüedad: 16 años, 5 meses
Puntos: 61
Respuesta: Juego 4 en raya

Es posible hacer el chequeo mucho mas económicamente, tanto en el tamaño del código como en la complejidad del mismo:

- no requiere hacer loops,
- solo requiere hacer un número fijo de adiciones y comparaciones.
- pero requiere mantener 2 arreglos y 2 enteros.

Esto es lo que se asume, o se fabrica:

- Suponemos que la matriz está llena de 0s inicialmente.
- Poner una de las 2 opciones cambia el 0 por 1 y poner la otra opcion cambia el 0 por -1.

La gracia de esto es que se sabe si hay 4 en linea si al sumar una fila el resultado da N o -N, pero NO ES NECESARIO sumar toda la fila (o todas las filas) o toda la columna (o todas las columnas).

- Se mantiene 2 arreglos: suma_fila[N], suma_columna[N], que guardan la suma de cada fila y columna, parten en 0.
- Cada vez que se juega alguna opción se actualiza solo 1 posicion de cada arreglo, y solo se chequea si ese valor cambio a N (o -N). No es posible que OTRA FILA haya hecho gato si estoy jugando en una.
- La diagonal o contradiagonal solo son 1 entero, tambien parten en 0.

Finalmente el codigo podria ser algo asi (podria tener errores menores)

Código C++:
Ver original
  1. bool hayGato( int fila, int columna, int jugada ) {   // "jugada" es 1 o -1
  2.     assert( abs(jugada) == 1 );
  3.     suma_fila[fila] += jugada;
  4.     suma_columna[columna] += jugada;
  5.     if( fila == columna ) suma_diagonal += jugada;
  6.     if( fila + columna == N-1 ) suma_antidiagonal += jugada;
  7.  
  8.     return abs( suma_fila[fila] ) == N || abs( suma_columna[columna] ) == N ||
  9.            abs(suma_diagonal) == N || abs(suma_antidiagonal) == N;
  10. }

Ahi está: El chequeo en menos de 10 líneas, sin loops
__________________
Visita mi perfil en LinkedIn

Última edición por CalgaryCorpus; 06/06/2014 a las 10:12
  #6 (permalink)  
Antiguo 06/06/2014, 10:14
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 14 años, 1 mes
Puntos: 10
Respuesta: Juego 4 en raya

Ahora me dan ganas de borrar mi código por vergüenza
(que por cierto, para las diagonales no habría que hacer las cuatro combinaciones sino que con 2 serían suficientes, aunque....."ya pa qué")
  #7 (permalink)  
Antiguo 06/06/2014, 10:31
 
Fecha de Ingreso: junio-2008
Ubicación: Seattle, USA
Mensajes: 733
Antigüedad: 16 años, 5 meses
Puntos: 61
Respuesta: Juego 4 en raya

Resolver el problema de 4 en raya en un tablero de 4x4 se puede simplificar como he mostrado.
Ahora cómo resolver el problema de 4 en raya en un tablero de 6x7 seguro resulta mas complejo que lo mostrado. ¿o no?
Simplificaciones posibles:
- no es necesario hacer todos los recorridos todas las veces cuando se sabe que la ultima jugada pasó por la coordenada (fila,columna).
- Es facil saber que la ultima jugada no ha hecho 4 si la suma es menor que 4. Solo es necesario chequear si la suma es 4 o más.
__________________
Visita mi perfil en LinkedIn

Última edición por CalgaryCorpus; 06/06/2014 a las 10:39
  #8 (permalink)  
Antiguo 06/06/2014, 12:46
 
Fecha de Ingreso: junio-2014
Ubicación: San Vicente del Raspeig
Mensajes: 9
Antigüedad: 10 años, 5 meses
Puntos: 0
Respuesta: Juego 4 en raya

Muchas gracias por la ayuda pero ya he resuelto mi problema. Aqui os dejo el código y si alguien quiere el mainwindow.ui tambien puedo pasarlo pero es demasiado largo por eso he preferido dejarlo.

Código C++:
Ver original
  1. <mainwindow.h>
  2. #ifndef MAINWINDOW_H
  3. #define MAINWINDOW_H
  4.  
  5. #include <QMainWindow>
  6. #include <QPushButton>
  7.  
  8. namespace Ui {
  9. class MainWindow;
  10. }
  11.  
  12. class MainWindow : public QMainWindow
  13. {
  14.     Q_OBJECT
  15.  
  16. public:
  17.     explicit MainWindow(QWidget *parent = 0);
  18.     ~MainWindow();
  19.  
  20. private slots:
  21.  
  22.     void on_actionSalir_triggered();
  23.  
  24.     void on_actionAcerca_de_triggered();
  25.  
  26.     void on_actionNuevo_Juego_triggered();
  27.  
  28.     void on_pushButton_7_clicked();
  29.  
  30.     void on_pushButton_9_clicked();
  31.  
  32.     void on_pushButton_11_clicked();
  33.  
  34.     void on_pushButton_13_clicked();
  35.  
  36.     void on_pushButton_15_clicked();
  37.  
  38.     void on_pushButton_17_clicked();
  39.  
  40.     void on_pushButton_19_clicked();
  41.  
  42.     void BotonPulsado(int columna);
  43.  
  44.     void Ganado(int fila,int columna,int ficha);
  45.  
  46.     bool Comprobar4EnLinea(int fila,int columna,int incFila,int incColumna);
  47.  
  48.     bool ComprobarDiagonalIzquierda(int fila,int columna);
  49.  
  50.     bool ComprobarDiagonalDerecha(int fila,int columna);
  51.  
  52.     bool ComprobarVertical(int fila,int columna);
  53.  
  54.     bool ComprobarHorizontal(int fila,int columna);
  55.  
  56. private:
  57.     //declaracion de los atributos necesarios para nuestro codigo.
  58.     Ui::MainWindow *ui;
  59.     QPushButton *M[6][7];
  60.     int V[7];
  61.     int Mint[6][7];
  62.     int empate;
  63.     bool turno;
  64.     bool ganadorojas;
  65.     bool ganadoamar;
  66. };
  67.  
  68. #endif // MAINWINDOW_H
  69. ---------------------------------------------------------------------------------------------------------------------
  70. <main.cpp>
  71. #include "mainwindow.h"
  72. #include <QApplication>
  73.  
  74.  
  75. int main(int argc, char *argv[])
  76. {
  77.     QApplication a(argc, argv);
  78.     MainWindow w;
  79.     w.show();
  80.  
  81.     return a.exec();
  82. }
  83. ----------------------------------------------------------------------------------------------------------------------
  84. <mainwindow.cpp>
  85. #include "mainwindow.h"
  86. #include "ui_mainwindow.h"
  87.  
  88. //librerias para las distinas opciones
  89. #include <QMessageBox>
  90. #include <QPushButton>
  91. #include <QIcon>
  92.  
  93. //Constructor de la ventana principal
  94. MainWindow::MainWindow(QWidget *parent) :
  95.     QMainWindow(parent),
  96.     ui(new Ui::MainWindow)
  97. {
  98.     //Inicializacion de la ventana.
  99.     ui->setupUi(this);
  100.  
  101.     //Asignacion de los botones a las distintas posiciones de la matriz.
  102.     M[0][0] = ui->pushButton_8;
  103.     M[0][1] = ui->pushButton_10;
  104.     M[0][2] = ui->pushButton_12;
  105.     M[0][3] = ui->pushButton_14;
  106.     M[0][4] = ui->pushButton_16;
  107.     M[0][5] = ui->pushButton_18;
  108.     M[0][6] = ui->pushButton_20;
  109.     M[1][0] = ui->pushButton_21;
  110.     M[1][1] = ui->pushButton_22;
  111.     M[1][2] = ui->pushButton_23;
  112.     M[1][3] = ui->pushButton_24;
  113.     M[1][4] = ui->pushButton_25;
  114.     M[1][5] = ui->pushButton_26;
  115.     M[1][6] = ui->pushButton_27;
  116.     M[2][0] = ui->pushButton_28;
  117.     M[2][1] = ui->pushButton_29;
  118.     M[2][2] = ui->pushButton_30;
  119.     M[2][3] = ui->pushButton_31;
  120.     M[2][4] = ui->pushButton_32;
  121.     M[2][5] = ui->pushButton_33;
  122.     M[2][6] = ui->pushButton_34;
  123.     M[3][0] = ui->pushButton_35;
  124.     M[3][1] = ui->pushButton_36;
  125.     M[3][2] = ui->pushButton_37;
  126.     M[3][3] = ui->pushButton_38;
  127.     M[3][4] = ui->pushButton_39;
  128.     M[3][5] = ui->pushButton_40;
  129.     M[3][6] = ui->pushButton_41;
  130.     M[4][0] = ui->pushButton_42;
  131.     M[4][1] = ui->pushButton_43;
  132.     M[4][2] = ui->pushButton_44;
  133.     M[4][3] = ui->pushButton_45;
  134.     M[4][4] = ui->pushButton_46;
  135.     M[4][5] = ui->pushButton_47;
  136.     M[4][6] = ui->pushButton_48;
  137.     M[5][0] = ui->pushButton_49;
  138.     M[5][1] = ui->pushButton_50;
  139.     M[5][2] = ui->pushButton_51;
  140.     M[5][3] = ui->pushButton_52;
  141.     M[5][4] = ui->pushButton_53;
  142.     M[5][5] = ui->pushButton_54;
  143.     M[5][6] = ui->pushButton_55;
  144.  
  145.     for(int i=0;i<7;i++){
  146.         V[i]=0;
  147.     }
  148.     for(int j=0;j<6;j++){
  149.         for(int k=0;k<7;k++){
  150.             Mint[j][k]=0;
  151.         }
  152.     }
  153.     empate=0;
  154.     turno=true;
  155.     ganadorojas=false;
  156.     ganadoamar=false;
  157.  
  158. }
  159. //Destructor
  160. MainWindow::~MainWindow()
  161. {
  162.     delete ui;
  163. }
  164. //funcion salir triggered
  165. void MainWindow::on_actionSalir_triggered()
  166. {
  167.     close();
  168. }
  169. //funcion acerca de triggered
  170. void MainWindow::on_actionAcerca_de_triggered()
  171. {
  172.     QMessageBox::information(this,"Acerca del Juego","Realizado por Alvaro Garrido Tafalla y Jorge Medina Carbonell","Aceptar");
  173. }
  174. //funcion reiniciar juego triggered
  175. void MainWindow::on_actionNuevo_Juego_triggered()
  176. {
  177.     for(int i=0;i<6;i++){
  178.         for(int j=0;j<7;j++){
  179.             M[i][j]->setIcon(QIcon(":/Iconos/Material ejercicio 1/circle_grey.png"));
  180.             Mint[i][j]=0;
  181.         }
  182.     }
  183.     for(int i=0;i<7;i++){
  184.         V[i]=0;
  185.     }
  186.     turno=true;
  187.     ganadorojas=false;
  188.     ganadoamar=false;
  189.     empate=0;
  190.     ui->label->setText("Turno de las rojas");
  191. }
  192. //Funciones clicked de cada boton del panel, que llaman a la funcion BotonPulsado
  193. void MainWindow::on_pushButton_7_clicked()
  194. {
  195.     BotonPulsado(0);
  196. }
  197. void MainWindow::on_pushButton_9_clicked()
  198. {
  199.     BotonPulsado(1);
  200. }
  201. void MainWindow::on_pushButton_11_clicked()
  202. {
  203.     BotonPulsado(2);
  204. }
  205. void MainWindow::on_pushButton_13_clicked()
  206. {
  207.     BotonPulsado(3);
  208. }
  209. void MainWindow::on_pushButton_15_clicked()
  210. {
  211.     BotonPulsado(4);
  212. }
  213. void MainWindow::on_pushButton_17_clicked()
  214. {
  215.     BotonPulsado(5);
  216. }
  217. void MainWindow::on_pushButton_19_clicked()
  218. {
  219.     BotonPulsado(6);
  220. }
  221. //funcion BotonPulsado que permite cambir el icono de los botones.
  222. void MainWindow::BotonPulsado(int columna)
  223. {
  224.     if(V[columna]<6){//comprueba que no se tira sobre una columna llena
  225.         int pos=5-V[columna];
  226.         V[columna]=V[columna]+1;
  227.         if(turno==true){
  228.             M[pos][columna]->setIcon(QIcon(":/Iconos/Material ejercicio 1/circle_red.png"));
  229.             Mint[pos][columna]=1;
  230.             turno=false;
  231.             ui->label->setText("Turno de las amarillas");
  232.             Ganado(pos,columna,1);
  233.         }else{
  234.             M[pos][columna]->setIcon(QIcon(":/Iconos/Material ejercicio 1/circle_yellow.png"));
  235.             Mint[pos][columna]=2;
  236.             turno=true;
  237.             ui->label->setText("Turno de las rojas");
  238.             Ganado(pos,columna,2);
  239.         }
  240.         empate++;
  241.     }
  242. }
  243. //Ganador o Empate
  244. void MainWindow::Ganado(int fila,int columna,int ficha)
  245. {
  246.     bool ganador=false;
  247.  
  248.     ganador |= ComprobarDiagonalDerecha(fila,columna);
  249.     ganador |= ComprobarDiagonalIzquierda(fila,columna);
  250.     ganador |= ComprobarVertical(fila,columna);
  251.     ganador |= ComprobarHorizontal(fila,columna);
  252.  
  253.     if(ganador){
  254.         if(ficha==1){
  255.             QMessageBox::information(this,"Fin de juego","Ganan las Rojas","OK");
  256.         }else{
  257.             QMessageBox::information(this,"Fin de juego","Ganan las Amarillas","OK");
  258.         }
  259.         on_actionNuevo_Juego_triggered();
  260.     }
  261.     if(empate==41){
  262.         QMessageBox::information(this,"Fin de juego","Rojas y Amarillas han quedado empate","OK");
  263.         on_actionNuevo_Juego_triggered();
  264.     }
  265. }
  266. //comprueba la diagonal derecha
  267. bool MainWindow::ComprobarDiagonalDerecha( int fila, int columna)
  268. {
  269.   bool encontrado=false;
  270.   // Se prueban todas las combinaciones en las que esta involucrada la ficha recien puesta
  271.   for(int i=0;i<4;i++){
  272.     if(Comprobar4EnLinea(fila+i,columna+i,1,-1)){
  273.       encontrado=true;
  274.       break;
  275.     }
  276.   }
  277.   return encontrado;
  278. }
  279. //comprueba la diagonal izquierda
  280. bool MainWindow::ComprobarDiagonalIzquierda( int fila, int columna)
  281. {
  282.     bool encontrado=false;
  283.     // Se prueban todas las combinaciones en las que esta involucrada la ficha recien puesta
  284.     for(int i=0;i<4;i++){
  285.         if(Comprobar4EnLinea(fila + i,columna + i,-1,-1)){
  286.             encontrado=true;
  287.             break;
  288.         }
  289.     }
  290.     return encontrado;
  291. }
  292. //comprueba las verticales
  293. bool MainWindow::ComprobarVertical(int fila,int columna)
  294. {
  295.     bool encontrado=false;
  296.     for(int i=0;i<4;i++){
  297.         if(Comprobar4EnLinea(fila+i,columna,-1,0)){
  298.             encontrado=true;
  299.             break;
  300.         }
  301.     }
  302.     return encontrado;
  303. }
  304. //comprueba las horizontales
  305. bool MainWindow::ComprobarHorizontal(int fila,int columna)
  306. {
  307.     bool encontrado=false;
  308.     for(int i=0;i<4;i++){
  309.         if(Comprobar4EnLinea(fila,columna+i,0,-1)){
  310.             encontrado=true;
  311.             break;
  312.         }
  313.     }
  314.     return encontrado;
  315. }
  316. // comprueba si ha hecho 4 en linea
  317. bool MainWindow::Comprobar4EnLinea(int fila,int columna,int incFila,int incColumna )
  318. {
  319.     bool encontrado=true;
  320.     if(fila>=0 && fila<6 && columna>=0 && columna<7){
  321.         int ficha=Mint[fila][columna];
  322.         for(int i=0;i<3;i++){
  323.             fila+=incFila;
  324.             columna+=incColumna;
  325.             if(fila>=0 && fila<6 && columna>=0 && columna<7){
  326.                 if(Mint[fila][columna]!=ficha){
  327.                     encontrado=false;
  328.                     break;
  329.                 }
  330.             }else{
  331.                 encontrado=false;
  332.             }
  333.         }
  334.     }else{
  335.         encontrado=false;
  336.     }
  337.     return encontrado;
  338. }
  339. ----------------------------------------------------------------------------------------------------------------------
  #9 (permalink)  
Antiguo 06/06/2014, 12:53
 
Fecha de Ingreso: junio-2014
Ubicación: San Vicente del Raspeig
Mensajes: 9
Antigüedad: 10 años, 5 meses
Puntos: 0
Respuesta: Juego 4 en raya

He intentado pasa el mainwindow.ui y es demasiado largo y no admite tantos caracteres.
  #10 (permalink)  
Antiguo 09/06/2014, 04:30
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 14 años, 1 mes
Puntos: 10
Respuesta: Juego 4 en raya

Cita:
Iniciado por CalgaryCorpus Ver Mensaje
Resolver el problema de 4 en raya en un tablero de 4x4 se puede simplificar como he mostrado.
Ahora cómo resolver el problema de 4 en raya en un tablero de 6x7 seguro resulta mas complejo que lo mostrado. ¿o no?
Simplificaciones posibles:
- no es necesario hacer todos los recorridos todas las veces cuando se sabe que la ultima jugada pasó por la coordenada (fila,columna).
- Es facil saber que la ultima jugada no ha hecho 4 si la suma es menor que 4. Solo es necesario chequear si la suma es 4 o más.
Hola, la verdad es que te respondí sin haber entendido el código. Estas cosas me llevan varias horas. Y la verdad es que no termino de entender el código.
¿Como funcionan suma_fila[] y suma_columna[]
Cita:
Es facil saber que la ultima jugada no ha hecho 4 si la suma es menor que 4. Solo es necesario chequear si la suma es 4 o más
¿Qué quiere decir esto exactamente?

@alvarogt91

Me alegro que hayas resuelto el tema.
Pero hay una cosa que no entiendo (lo pregunto para el que me lo pueda responer)

Código C++:
Ver original
  1. //Ganador o Empate
  2. void MainWindow::Ganado(int fila,int columna,int ficha)
  3. {
  4.     bool ganador=false;
  5.  
  6.     ganador |= ComprobarDiagonalDerecha(fila,columna);
  7.     ganador |= ComprobarDiagonalIzquierda(fila,columna);
  8.     ganador |= ComprobarVertical(fila,columna);
  9.     ganador |= ComprobarHorizontal(fila,columna);
  10.    ...................................................................
  11. }

¿Cómo se leen esas líneas?

Por cierto, aunque soy pesado (es que estoy metiendo las manazas en Qt y por eso me interesa todo esto), has probado a enviar el archivo ui_mainwindow.h, a ver si éste si cabe (aunque sea en dos post)

Saludos y gracias!
  #11 (permalink)  
Antiguo 09/06/2014, 07:49
 
Fecha de Ingreso: junio-2008
Ubicación: Seattle, USA
Mensajes: 733
Antigüedad: 16 años, 5 meses
Puntos: 61
Respuesta: Juego 4 en raya

Si sumas 1 por cada vez que alguien pone x en la fila 1 sabes que no hay 4 en la fila 1 si la suma es menor que 4. Lo mismo para el resto de filas y columnas.
Pero para lograrlo se requeriria mantener tantas sumas como filas y columnas. De ahi los arreglos mencionados.
__________________
Visita mi perfil en LinkedIn
  #12 (permalink)  
Antiguo 10/06/2014, 01:44
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 14 años, 1 mes
Puntos: 10
Respuesta: Juego 4 en raya

Gracias CalgaryCorpus. Ahora sí entiendo la idea.

Por cierto, y sobre estas sentencias...¿cómo se interpretan?
Código C++:
Ver original
  1. ganador |= ComprobarDiagonalDerecha(fila,columna);

Gracias!
  #13 (permalink)  
Antiguo 10/06/2014, 04:50
 
Fecha de Ingreso: junio-2008
Ubicación: Seattle, USA
Mensajes: 733
Antigüedad: 16 años, 5 meses
Puntos: 61
Respuesta: Juego 4 en raya

En el fondo solo cambia la variable si la expresion es 1 (verdadera)

Similar a

Código C++:
Ver original
  1. if( ComprobarDiagonalDerecha(fila,columna) )
  2.   ganador = 1;

Si la expresion es falsa, no hay cambios.
__________________
Visita mi perfil en LinkedIn
  #14 (permalink)  
Antiguo 10/06/2014, 12:00
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 14 años, 1 mes
Puntos: 10
Respuesta: Juego 4 en raya

Gracias siempre por responder CalgaryCorpus.
A sabiendas de que le estoy desvirtuando el hilo a su dueño.....

Entonces, esto sólo funciona partiendo de false, y además si llego a true no hay vuelta atrás, no?

Hago así:
Código C++:
Ver original
  1. bool verdad=false;
  2.     cout<<verdad<<endl;
  3.     verdad |=(5>4);
  4.     cout<<verdad<<endl;
  5.     verdad |=(3==2);
  6.     cout<<verdad<<endl;

Y aunque la última expresión no es cierta, ya no vuelvo al valor false, por lo que veo.
¿Es así?
  #15 (permalink)  
Antiguo 10/06/2014, 16:22
 
Fecha de Ingreso: junio-2008
Ubicación: Seattle, USA
Mensajes: 733
Antigüedad: 16 años, 5 meses
Puntos: 61
Respuesta: Juego 4 en raya

Es cierto que si llegas a true, la expresión que comentamos se asegura que siempre quede así, pero no estás obligado a partir de false. Si partes de true, también permanecerá en true, por lo que estoy de acuerdo con lo que dices excepto con la frase "Entonces, esto sólo funciona partiendo de false", porque tambien funciona cuando partes en true.

Ahora, reconozo que para este ejercicio, en donde se está ocupando esta técnica, sólo tiene sentido partir en false y finalmente ver si alguna vez se convirtió en true.
__________________
Visita mi perfil en LinkedIn

Última edición por CalgaryCorpus; 11/06/2014 a las 04:02
  #16 (permalink)  
Antiguo 11/06/2014, 04:58
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 14 años, 1 mes
Puntos: 10
Respuesta: Juego 4 en raya

Gracias, ya me queda claro

Etiquetas: funcion, int, juego, programa, raya
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 16:18.