Hi everyone, started college 2 months ago and really liking Pascal classes so far. Never programmed before, so I could use a little help with this.
About 1 week ago I started on my semester's final project: we have to create a Candy Crush clone (Color Crush) which functions basically like the game.
8 days later I finally finished the program, and as far as I can tell it works well in Linux. However, when running the compiled .exe under Windows, as soon as I start the game (by pressing J) it exits itself with a runtime error 201. I know this means there's a problem with the arrays used, but I don't understand why it works perfectly in Linux/where the problem could be.
Here's the entire program, because I honestly don't know what could be causing the problem:
Program ColorCrush;
Uses CRT;
Const
MaxFil = 10;
MinFilVisible = 6;
MinFil = 1;
MaxCol = 5;
MinCol = 1;
Moves = 5;
Arriba1 = 'W';
Arriba2 = 'w';
Abajo1 = 'S';
Abajo2 = 's';
Derecha1 = 'D';
Derecha2 = 'd';
Izquierda1 = 'A';
Izquierda2 = 'a';
Azul = 'A ';
Blanco = 'B ';
Rojo = 'R ';
Verde = 'V ';
Type CandyMat = array [MinFil..MaxFil,MinCol..MaxCol] of String;
Type ArregloPunt = array [1..10] of Integer;
Type ArregloNick = array [1..10] of String;
Procedure AnalizarValor (Var MatrizCandy : CandyMat;Valor,I,J : Integer);
begin
If Valor = 0 then
MatrizCandy[I,J] := Azul;
If Valor = 1 then
MatrizCandy[I,J] := Blanco;
If Valor = 2 then
MatrizCandy[I,J] := Rojo;
If Valor = 3 then
MatrizCandy[I,J] := Verde;
end;
Procedure CargarCrush (Var MatrizCandy : CandyMat; InicioF,FinF,InicioC,FinC : Integer);
Var I,J,X : Integer;
begin
For I := InicioF to FinF do
For J := InicioC to FinC do
begin
X := Random(4);
AnalizarValor(MatrizCandy,X,I,J);
end;
end;
Procedure InicCrush (Var MatrizCandy : CandyMat);
Var I,J : Integer;
begin
Randomize;
For I := MinFil to MaxFil do
For J := MinCol to MaxCol do
CargarCrush(MatrizCandy,I,MaxFil,J,MaxCol);
end;
Function ReconstruirVertical (MatrizCandy : CandyMat;InicioF,FinF,InicioC,FinC:Integer) : Boolean;
Var I,J : Integer;
begin
ReconstruirVertical := False;
For J := InicioC to FinC do
For I := InicioF to FinF do
If (I <= MaxFil - 2) and (MatrizCandy[I,J] = MatrizCandy[I+1,J]) and (MatrizCandy[I+1,J] = MatrizCandy[I+2,J]) then
ReconstruirVertical := True;
end;
Function ReconstruirHorizontal (MatrizCandy : CandyMat;InicioF,FinF,InicioC,FinC:Integer) : Boolean;
Var I,J : Integer;
begin
ReconstruirHorizontal := False;
For I := InicioF to FinF do
For J := InicioC to FinC do
If (J <= MaxCol - 2) and (MatrizCandy[I,J] = MatrizCandy[I,J+1]) and (MatrizCandy[I,J+1] = MatrizCandy[I,J+2]) then
ReconstruirHorizontal := True;
end;
Function Reconstruir (MatrizCandy : CandyMat;InicioF,FinF,InicioC,FinC:Integer) : Boolean;
Var I,J : Integer;
begin
Reconstruir := False;
For I := InicioF to FinF do
For J := InicioC to FinC do
If ((J <= MaxCol - 2) and (MatrizCandy[I,J] = MatrizCandy[I,J+1]) and (MatrizCandy[I,J+1] = MatrizCandy[I,J+2])) or ((I <= MaxFil - 2) and (MatrizCandy[I,J] = MatrizCandy[I+1,J]) and (MatrizCandy[I+1,J] = MatrizCandy[I+2,J])) then
Reconstruir := True;
end;
Procedure MostrarCandyC (MatrizCandy : CandyMat);
Var I,J : Integer;
begin
For I := MinFilVisible to MaxFil do
begin
WriteLn('');
For J := MinCol to MaxCol do
begin
If MatrizCandy[I,J] = Azul then
begin
TextColor(Blue);
Write(MatrizCandy[I,J]);
end;
If MatrizCandy[I,J] = Blanco then
begin
TextColor(8);
Write(MatrizCandy[I,J]);
end;
If MatrizCandy[I,J] = Rojo then
begin
TextColor(Red);
Write(MatrizCandy[I,J]);
end;
If MatrizCandy[I,J] = Verde then
begin
TextColor(Green);
Write(MatrizCandy[I,J]);
end;
end;
end;
WriteLn('');
TextColor(7);
end;
Function CoincidenciaHorizontal (MatrizCandy : CandyMat; Fila,Columna : Integer) : Boolean;
begin
CoincidenciaHorizontal := False;
If (Columna <= MaxCol - 2) and (MatrizCandy[Fila,Columna] = MatrizCandy[Fila,Columna+1]) and (MatrizCandy[Fila,Columna+1] = MatrizCandy[Fila,Columna+2]) then
CoincidenciaHorizontal := True;
end;
Function CoincidenciaVertical (MatrizCandy : CandyMat; Fila,Columna : Integer) : Boolean;
begin
CoincidenciaVertical := False;
If (Fila <= MaxFil - 2) and (MatrizCandy[Fila,Columna] = MatrizCandy[Fila+1,Columna]) and (MatrizCandy[Fila+1,Columna] = MatrizCandy[Fila+2,Columna]) then
CoincidenciaVertical := True;
end;
Function PuntajeHorizontal (MatrizCandy : CandyMat; Fila,InCol,FinCol : Integer) : Integer;
Var Y,X : Integer;
begin
X := FinCol - InCol + 1;
If MatrizCandy[Fila,InCol] = Rojo then
Y := X else
If MatrizCandy[Fila,InCol] = Verde then
Y := 2*X else
If MatrizCandy[Fila,InCol] = Azul then
Y := 3*X else
If MatrizCandy[Fila,InCol] = Blanco then
Y := 4*X;
PuntajeHorizontal := Y;
end;
Function PuntajeVertical (MatrizCandy : CandyMat; Columna,InFil,FinFil : Integer) : Integer;
Var X,Y : Integer;
begin
begin
X := FinFil - InFil + 1;
If MatrizCandy[InFil,Columna] = Rojo then
Y := X else
If MatrizCandy[InFil,Columna] = Verde then
Y := 2*X else
If MatrizCandy[InFil,Columna] = Azul then
Y := 3*X else
If MatrizCandy[InFil,Columna] = Blanco then
Y := 4*X;
PuntajeVertical:= Y;
end;
end;
Procedure Reemplazo (Var MatrizCandy : CandyMat; InicioF,FinF,InicioC,FinC : Integer);
Var I,J : Integer;
begin
For I := InicioF to FinF do
For J := InicioC to FinC do
begin
Randomize;
While (MatrizCandy[I,J] = MatrizCandy[I,J+1]) and (MatrizCandy[I,J] = MatrizCandy[I,J+2]) do
CargarCrush(MatrizCandy,I,I,J+2,J+2);
While (MatrizCandy[I,J] = MatrizCandy[I+1,J]) and (MatrizCandy[I,J] = MatrizCandy[I+2,J]) do
CargarCrush(MatrizCandy,I+2,I+2,J,J);
end;
end;
Procedure CaidaHorizontal (Var MatrizCandy : CandyMat;Var Puntaje : Integer);
Var I,J,K,L,X,Q,Z : Integer;
begin
X := 0;
While ReconstruirHorizontal(MatrizCandy,MinFilVisible,MaxFil,MinCol,MaxCol) do
begin
For I := MinFilVisible to MaxFil do
begin
For J := MinCol to MaxCol do
begin
If CoincidenciaHorizontal(MatrizCandy,I,J) then
begin
X := X + 1;
If X = 1 then
begin
K := I;
L := J;
end;
end else
If X > 0 then
begin
Puntaje := Puntaje + PuntajeHorizontal(MatrizCandy,K,L,L+X+1);
For Z := L to L+X+1 do
For Q := K downto MinFilVisible do
MatrizCandy[Q,Z] := MatrizCandy[Q-1,Z];
CargarCrush(MatrizCandy,MinFilVisible,MinFilVisible,L,L+X+1);
Randomize;
Reemplazo(MatrizCandy,MinFilVisible,MinFilVisible,L,L+X+1);
X := 0;
MostrarCandyC(MatrizCandy);
end;
end;
end;
MostrarCandyC(MatrizCandy);
end;
end;
Procedure CaidaVertical (Var MatrizCandy : CandyMat;Var Puntaje : Integer);
Var I,J,K,L,X,Z : Integer;
begin
X := 0;
While ReconstruirVertical(MatrizCandy,MinFilVisible,MaxFil,MinCol,MaxCol) do
begin
For J := MinCol to MaxCol do
For I := MinFilVisible to MaxFil do
begin
If CoincidenciaVertical(MatrizCandy,I,J) then
begin
X := X + 1;
If X = 1 then
begin
K := I;
L := J;
end;
end else
If X > 0 then
begin
Puntaje := Puntaje + PuntajeVertical(MatrizCandy,L,K,K+X+1);
Randomize;
CargarCrush(MatrizCandy,MinFil,MinFilVisible-1,MinCol,MaxCol);
Reemplazo(MatrizCandy,MinFil,MinFilVisible-1,MinCol,MaxCol);
For Z := K+X+1 downto K do
MatrizCandy[Z,L] := MatrizCandy[Z-X-2,L];
X := 0;
MostrarCandyC(MatrizCandy);
end;
end;
end;
MostrarCandyC(MatrizCandy);
end;
Procedure Intercambio (Var MatrizCandy : CandyMat; Fila,Columna:Integer);
Var Letra : Char; Var Aux : String;
begin
WriteLn('');
WriteLn('Seleccione la posición con la cual desea intercambiar el elemento - W (arriba) / S (abajo) / D (Derecha) / A (Izquierda)');
Letra := ReadKey;
While ((Letra <> Arriba1) and (Letra <> Arriba2) and (Letra <> Izquierda1) and (Letra <> Izquierda2) and (Letra <> Abajo1) and (Letra <> Abajo2) and (Letra <> Derecha1) and (Letra <> Derecha2)) or
(((Letra = Arriba1) and (Fila = 1)) or
((Letra = Arriba2) and (Fila = 1)) or
((Letra = Izquierda1) and (Columna = 1)) or
((Letra = Izquierda2) and (Columna = 1)) or
((Letra = Abajo1) and (Fila = MaxFil)) or
((Letra = Abajo2) and (Fila = MaxFil)) or
((Letra = Derecha1) and (Columna = MaxCol)) or
((Letra = Derecha2) and (Columna = MaxCol))) do
begin
WriteLn('Posición/Comando inválido, vuelva a intentar - W (Arriba) / A (Izquierda) / S (Abajo) / D (Derecha)');
Letra := ReadKey;
end;
If (Letra = Arriba1) or (Letra = Arriba2) then
begin
Aux := MatrizCandy [Fila-1,Columna];
MatrizCandy[Fila-1,Columna] := MatrizCandy [Fila,Columna];
MatrizCandy[Fila,Columna] := Aux;
end;
If (Letra = Abajo1) or (Letra = Abajo2) then
begin
Aux := MatrizCandy [Fila+1,Columna];
MatrizCandy[Fila+1,Columna] := MatrizCandy [Fila,Columna];
MatrizCandy[Fila,Columna] := Aux;
end;
If (Letra = Izquierda1) or (Letra = Izquierda2) then
begin
Aux := MatrizCandy [Fila,Columna-1];
MatrizCandy[Fila,Columna-1] := MatrizCandy [Fila,Columna];
MatrizCandy[Fila,Columna] := Aux;
end;
If (Letra = Derecha1) or (Letra = Derecha2) then
begin
Aux := MatrizCandy [Fila,Columna+1];
MatrizCandy[Fila,Columna+1] := MatrizCandy [Fila,Columna];
MatrizCandy[Fila,Columna] := Aux;
end;
end;
Procedure InicPunt (Var ArrPunt : ArregloPunt);
Var J : Integer;
begin
For J := 1 to 10 do
ArrPunt[J] := 0;
end;
Procedure InicNicks (Var ArrNicks : ArregloNick);
Var J : Integer;
begin
For J := 1 to 10 do
ArrNicks[J] := '0';
end;
Function CalcPosPuntaje(Puntaje : Integer;ArrPunt : ArregloPunt) : Integer;
Var J,I : Integer;
begin
I := 1;
For J := 1 to 10 do
If Puntaje < ArrPunt[J] then
I := I + 1;
CalcPosPuntaje := I;
end;
Procedure CargarPuntaje(Var Puntaje : Integer; Var ArrPunt : ArregloPunt);
Var J,I : Integer;
begin
I := CalcPosPuntaje(Puntaje,ArrPunt);
For J := 10 downto I do
ArrPunt[J+1] := ArrPunt[J];
ArrPunt[I] := Puntaje;
end;
Procedure CargarNicks(Nick : String; Var ArrNicks : ArregloNick;ArrPunt : ArregloPunt;Puntaje : Integer);
Var J,I : Integer;
begin
I := CalcPosPuntaje(Puntaje,ArrPunt);
For J := 10 downto I do
ArrNicks[J+1] := ArrNicks[J];
ArrNicks[I] := Nick;
end;
Procedure MostrarRanking (ArrNicks : ArregloNick; ArrPunt : ArregloPunt);
Var I : Integer;
begin
clrscr;
If ArrNicks[1] = '0' then
begin
WriteLn('');
WriteLn('Nadie ha jugador en esta sesión, ninguna puntuación ha sido cargada.');
WriteLn('');
end else
For I := 1 to 10 do
If ArrNicks[I] <> '0' then
WriteLn(I,'. ',ArrNicks[I],' - ',ArrPunt[I],' puntos');
end;
Procedure JuegoNuevo (Var Puntaje : Integer; Var TablaNicks : ArregloNick; Var TablaPuntaje : ArregloPunt);
Var MatrizCandy : CandyMat; Fila,Columna,Movimientos : Integer; Nick,Aux : String;
begin
Puntaje := 0;
InicCrush(MatrizCandy);
While Reconstruir (MatrizCandy,MinFil,MaxFil,MinCol,MaxCol) do
Reemplazo(MatrizCandy,MinFil,MaxFil,MinCol,MaxCol);
Movimientos := Moves;
MostrarCandyC(MatrizCandy);
While (Movimientos <> 0) do
begin
WriteLn('Movimientos restantes: ', Movimientos);
WriteLn('Seleccionar fila del elemento');
Read(Fila);
While (Fila+5 < MinFilVisible) or (Fila > MaxFil) do
begin
WriteLn('Ingrese una fila válida');
Read(Fila);
end;
WriteLn('Seleccionar columnna del elemento');
Read(Columna);
While (Columna < MinCol) or (Columna > MaxCol) do
begin
WriteLn('Ingrese una columna válida');
Read(Columna);
end;
Intercambio(MatrizCandy,Fila+5,Columna);
MostrarCandyC(MatrizCandy);
While Reconstruir(MatrizCandy,MinFilVisible,MaxFil,MinCol,MaxCol) do
begin
CaidaVertical(MatrizCandy,Puntaje);
CaidaHorizontal(MatrizCandy,Puntaje);
end;
WriteLn('Puntuación: ',Puntaje);
Movimientos := Movimientos - 1;
end;
If CalcPosPuntaje(Puntaje,TablaPuntaje) <= 10 then
begin
WriteLn('¡Felicidades, su puntuación está entre las mejores 10! Ingrese su nombre.');
ReadLn(Aux);
ReadLn(Nick);
CargarPuntaje(Puntaje,TablaPuntaje);
CargarNicks(Nick,TablaNicks,TablaPuntaje,Puntaje);
end else
WriteLn('Ha terminado la partida, se volverá al menú principal.');
Delay(1000);
end;
Var Puntaje : Integer; Var Opcion : Char; Var TablaPuntuacion : ArregloPunt; Var TablaNombres : ArregloNick;
begin
clrscr;
InicNicks(TablaNombres);
InicPunt(TablaPuntuacion);
Puntaje := 0;
Opcion := ' ';
While (Opcion <> 'S') and (Opcion <> 's') do
begin
WriteLn('Por favor ingrese una opción: [J]uego Nuevo - [R]anking - [S]alir');
Opcion := ReadKey;
Case Opcion of
'J','j': JuegoNuevo(Puntaje,TablaNombres,TablaPuntuacion);
'R','r': MostrarRanking(TablaNombres,TablaPuntuacion);
end;
end;
end.