PDA

Ver la Versión Completa : Memotest, juego con matrices


JoseGus
08-11-2011, 23:15:32
Hola a todos!

Necesito ayuda con un proyecto para la universidad, estoy haciendo un juego con matrices (Memotest, juego de buscar los pares). Necesito ayuda para hacer lo básico, de perfeccionarlo me encargo yo.

Hasta ahora he logrado cargar las imágenes en una matriz de 6x6 (la matriz está hecha usando las herramientas de FormPaint de Delphi). Tengo que cargar las imágenes de a pares, o sea, en una matriz de 6x6 hay 36 casillas, lo que es igual a 18 imágenes pares..

1. ¿Cómo hago para cargar las imágenes de a pares, para que una imagen no se repita dos 3 o mas veces en la matriz?
2. ¿Cómo hago para que al hacer click una imagen se de vuelta? Esto suponiendo que al momento de iniciar el juego todas las imágenes ya estan cargadas
pero están boca abajo.

Agradecería cualquier ayuda o idea, especialmente con mi primer pregunta.

Anexo el código de mi trabajo hasta el momento:

Formulario Principal:


unit UFPantalla;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,UCCuadricula, StdCtrls,JPEG;

type
TfrmPantalla = class(TForm)
Label1: TLabel;
procedure FormCreate(Sender: TObject);
procedure FormDblClick(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
private
{ Private declarations }
MC : Cuadricula;
Lista : Array[1..18] of TJPEGImage;
X,Y : Integer;
TA,TH: Integer;
public
{ Public declarations }
end;

var
frmPantalla: TfrmPantalla;

implementation

{$R *.dfm}

procedure TfrmPantalla.FormCreate(Sender: TObject);
var i: Integer;
begin
MC:=Cuadricula.Create;
MC.CargarEtepa(1);
Randomize;
for i:=1 to 18 do
begin
Lista[i]:=TJPEGImage.Create;
Lista[i].LoadFromFile('C:\Users\Familia\Desktop\MemoTest Imagenes\Imagenes
\im'+inttostr(i)+'.jpg');
end;
TA:=Trunc((Screen.Width div MC.NroColumnas)*0.9); //203
TH:=Trunc((Screen.Height div MC.NroFilas)*0.9); //115
X:=(Screen.Width-(MC.NroColumnas*TA)) div 2; //71
Y:=(Screen.Height-(MC.NroFilas*TH)) div 2; //39
end;

procedure TfrmPantalla.FormDblClick(Sender: TObject);
begin
Application.Terminate;
end;

procedure TfrmPantalla.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
Label1.Caption:='X: '+Inttostr(X)+' | '+'Y: '+Inttostr(Y);
if (X>=71) and (X<=1289) and (Y>=39) and (Y<=729) then
Screen.Cursor:=-21
else
Screen.Cursor:=crDefault;
end;

procedure TfrmPantalla.FormPaint(Sender: TObject);
var j,i,Px,Py: Integer;
begin

Canvas.Pen.Color:=clRed;
Canvas.Pen.Width:=1;
Canvas.Rectangle(X-1,Y-1,(TA*MC.NroColumnas)+X-1,(TH*MC.NroFilas)+Y-1);

Py:=Y;
for i:= 1 to MC.NroFilas do
begin
Px:=X;
for j:= 1 to MC.NroColumnas do
begin
//Canvas.StretchDraw(RECT(Px,Py,Px+Ta,Py+Th),Lista[MC.ObtenerImagen(i,j)]);
Canvas.Pen.Color:=clRed;
Canvas.Pen.Width:=1;
Canvas.Rectangle(Px-1,Py-1,Px+Ta+1,Py+Th+1);
Canvas.StretchDraw(RECT(Px,Py,Px+Ta,Py+Th),Lista[MC.ObtenerImagen(i,j)]);
Px:=Px+TA;
//Screen.Cursor:=-21;
end;
Py:=Py+TH;
end;
end;
end.

-----------------------------------------------------------------------

Unidad Creada:

unit UCCuadricula;

interface
Uses SysUtils, Math;
Const
MaxF=16;
MaxC=16;
Type
TCelda = Record
Img : Byte;
Estado : Byte;
End;
TCuadricula = Array[1..MaxF,1..MaxC] of TCelda;
Cuadricula = Class
Private
Filas,
Columnas : Word;
Celdas : TCuadricula;
Public
Constructor Create;
Procedure CargarEtepa(E : Byte);
Procedure ReDimensionar( F,C : Word);
Function NroFilas : Word;
Function NroColumnas : Word;
Procedure ColocarImagen(F,C:Word; I : Byte); //Carga la imagen, contenida entre un valor entre 1 y 256
Procedure CambiarEstado(F,C:Word; E : Byte); //Cambia el estado de la imagen (0=tapado; 1=visible)
Function ObtenerImagen(F,C:Word):Byte; //Devuelve la imagen en si, contenida entre un valor entre 1 y 256
Function ObtenerEstado(F,C:Word):Byte; //Devuelve el estado de la imagen (0=tapado; 1=visible)
End;

implementation

{ Cuadricula }

procedure Cuadricula.CambiarEstado(F, C: Word; E: Byte);
begin
If (F>0)and(F<=Filas)and(C>0)And(C<=Columnas) then
Celdas[F,C].Estado:=E
else raise Exception.Create('Error : Columna o Fila Incorrecta');
end;

procedure Cuadricula.CargarEtepa(E: Byte);
var i,j,c: Word;
a: byte;
begin
c:=0; a:=0;
Randomize;
for i:=1 to Filas do
for j:=1 to Columnas do
begin
Celdas[i,j].Img:=Random(18)+1;
Celdas[i,j].Estado:=0;
end;
end;

procedure Cuadricula.ColocarImagen(F, C: Word; I: Byte);
begin

end;

constructor Cuadricula.Create;
begin
Filas:=6;
Columnas:=6;
end;

function Cuadricula.NroColumnas: Word;
begin
Result:=Columnas;
end;

function Cuadricula.NroFilas: Word;
begin
Result:=Filas;
end;

function Cuadricula.ObtenerEstado(F, C: Word): Byte;
begin
Result:=Celdas[F,C].Estado;
end;

function Cuadricula.ObtenerImagen(F, C: Word): Byte;
begin
Result:=Celdas[F,C].Img;
end;

procedure Cuadricula.ReDimensionar(F, C: Word);
begin
Filas:=F;
Columnas:=C;
end;
end.

Casimiro Notevi
09-11-2011, 00:20:51
Bienvenido a clubdelphi, ¿ya leiste nuestra guía de estilo (http://www.clubdelphi.com/foros/guiaestilo.php)?, gracias por tu colaboración.

Esto no tiene nada que ver con "Internet", lo paso a "Varios".

Neftali [Germán.Estévez]
09-11-2011, 10:06:14
Hola JoseGus.
Bienvenido al Club.

Lo primero felicitarte, porque debes ser de los pocos que viene a pedir ayuda para un trabajo/práctica y se presenta con algo hecho y sabiendo lo que necesita. :):)
La mayoría ponen el enunciado del problema y dicen "¿Cómo se hace?" (o lo que es lo mismo, ¿Me lo hacéis?)


1. ¿Cómo hago para cargar las imágenes de a pares, para que una imagen no se repita dos 3 o mas veces en la matriz?


Hay varias opciones, algunas requieren más cambios que otras.
La más sencilla que se me ocurre es utilizar una lista intermedia (18 posiciones), para marcar qué números has utilizado ya y cuentas veces.
IDEA:
Empiezas con la lista vacia, utilizas un Ramdom(18) y si sale un 7 (por ejemplo), en la posición 7 de la lista colocas un 1 (porque ha salido una vez). Si luego sale un 5, en la posición 5 colocas un 1.... Cuando vuelva a salir el 7, en la posición 7 colocas un 2 (esto marca que el 7 ya ha salido 2 veces = la imagen 7 ya la has utilizado 2 veces). La siguiente vez que salga el 7, como ya lo has utilizado 2 veces, debes descartarlo.

Algo así:


var
list:Array[1..18] of integer;
j, i, asignados:Integer
begin
Asignados := 0;
Randomize;

While (asignados < 36) do begin

j := Random(18)+1; // te da un número entre 1 y 18

if (list[j] = 0) then begin // Este número no se ha usado
Asignar al tablero la imagen numero j
list[j] := 1; // marco que la he usado 1 vez
asignados := asignados + 1; // he asignado 1 imagen más
end
else if (list[j] = 1) then begin // Este número ya se ha usado 1 vez
Asignar al tablero la imagen numero j
list[j] := 2; // marco que la he usado 2 veces
asignados := asignados + 1; // he asignado 1 imagen más
end
else begin // si llego aquí es que ya la he usado 2 veces
// En este caso no hago nada; Me interesa que busque otro
// NADA
end;
end;


Es más o menos la idea.
Tal vez no compile alguna cosilla, ya que te lo he hecho de memoria.
Tendrás que inicializar el array a 0 (todas las posiciones).


2. ¿Cómo hago para que al hacer click una imagen se de vuelta? Esto suponiendo que al momento de iniciar el juego todas las imágenes ya estan cargadas
pero están boca abajo.


Bueno, lo que debes hacer, es que en visual tengas cargada inicialmente la misma imagen; Una imagen neutra que representa la parte trasera de la carta (un interrogante o cualquier otra).
Cuando un usuario pulsa un click sobre esa imagen, lo que hacer es cargar realmente la que tienes en la Lista[j] (la posición que corresponda).

No se si me he explicado.

Un saludo.