As matrizes expandem o conceito de vetores, que são estruturas unidimensionais (como uma lista). Uma matriz funciona como uma "tabela" bidimensional, com linhas e colunas, sendo ideal para representar problemas que dependem de uma disposição em duas dimensões, como coordenadas em um mapa, peças em um tabuleiro ou até mesmo os pixels de uma imagem.
Enquanto um vetor precisa de apenas um índice para acessar uma posição, uma matriz necessita de dois: um para a linha
e outro para a coluna. A indexação também começa em 0, então a primeira posição de uma matriz é (0,0). A principal
diferença na declaração em C# é o uso de uma vírgula dentro dos colchetes ([,]
) para indicar as duas
dimensões.
É possível definir os valores da matriz diretamente em sua criação. A formatação com múltiplas linhas ajuda a visualizar a estrutura, mas não é obrigatória.
double[,] notas = { { 8.7, 5.4, 6.2 }, { 3.8, 2.7, 8.5 }, { 9.1, 0.9, 4.2 }, { 7.1, 1.8, 8.8 } };
Para acessar ou alterar um valor, você deve sempre informar os dois índices (linha e coluna).
// Altera o valor na primeira linha, segunda coluna notas[0, 1] = 6.4; // Copia o valor da última linha e última coluna para uma variável double nota_do_antonio = notas[3, 2];
Você pode declarar uma matriz especificando o número de linhas e colunas, para depois preencher os valores.
double[,] notas = new double[4, 3];
Também é possível declarar a matriz e inicializá-la em outro ponto do código.
double[,] notas; notas = new double[4, 3];
Matrizes são perfeitas para jogos de tabuleiro como xadrez, damas ou, como no exemplo a seguir, Campo Minado.
Vamos usar uma matriz 10x10 para o campo, onde `0` é uma posição vazia, `1` é uma bomba e `2` é a bandeira. Outra matriz, `jogo`, registrará as ações do jogador.
Criação e inicialização do campo:
int[,] campo = new int[10, 10]; // Matriz com posições dos elementos do campo int[,] jogo = new int[10, 10]; // Matriz que registra ações do jogador int qtdLinhas = campo.GetLength(0); int qtdColunas = campo.GetLength(1); // Preenche a matriz 'campo' com 0 e a matriz 'jogo' com -1 for (int l = 0; l < qtdLinhas; l++) { for (int c = 0; c < qtdColunas; c++) { campo[l, c] = 0; jogo[l, c] = -1; } }
Para percorrer ou preencher uma matriz, a forma padrão é utilizar duas estruturas for
, uma dentro da
outra. O laço externo percorre as linhas, e o interno percorre as colunas.
Posicionamento aleatório dos elementos:
// Posicionamento aleatório da bandeira Random gerador = new Random(); int linha = gerador.Next(qtdLinhas); int coluna = gerador.Next(qtdColunas); campo[linha, coluna] = 2; // Posicionamento aleatório das 5 bombas int bombasPosicionadas = 0; do { linha = gerador.Next(qtdLinhas); coluna = gerador.Next(qtdColunas); if (campo[linha, coluna] == 0) { campo[linha, coluna] = 1; bombasPosicionadas++; } } while (bombasPosicionadas < 5);
Loop principal de interação com o jogador:
bool fimJogo = false; do { // Imprime o tabuleiro do jogador for (int l = 0; l < qtdLinhas; l++) { for (int c = 0; c < qtdColunas; c++) { Console.Write(string.Format("{0} ", jogo[l, c])); } Console.Write(Environment.NewLine + Environment.NewLine); } Console.Write("Selecione uma linha [1-10]: "); linha = Convert.ToInt32(Console.ReadLine()) - 1; Console.Write("Selecione uma coluna [1-10]: "); coluna = Convert.ToInt32(Console.ReadLine()) - 1; switch (campo[linha, coluna]) { case 0: jogo[linha, coluna] = 0; Console.Write("Continue tentando.\n\n"); break; case 1: jogo[linha, coluna] = 1; Console.Write("BOOOM. Você perdeu.\n\n"); fimJogo = true; break; default: jogo[linha, coluna] = 2; Console.Write("Parabéns. Você ganhou!\n\n"); fimJogo = true; break; } } while (!fimJogo);
Matrizes podem ser passadas como argumentos para funções, assim como os vetores. Uma observação importante é que matrizes (e vetores) são passadas por referência. Isso significa que qualquer alteração feita na matriz dentro da função se refletirá na matriz original, fora da função.
Código principal do jogo:
char[,] tabuleiro = new char[3, 3]; int linha, coluna; bool fimJogo = false; int jogador = 1; int jogada = 0; // Preenchimento da matriz com espaços em branco for (int l = 0; l < 3; l++) for (int c = 0; c < 3; c++) tabuleiro[l, c] = ' '; do { imprimirTabuleiro(tabuleiro); if (jogador == 1) Console.Write("JOGADOR 1:\n"); else Console.Write("JOGADOR 2:\n"); Console.Write("Selecione uma linha [1-3]: "); linha = Convert.ToInt32(Console.ReadLine()) - 1; Console.Write("Selecione uma coluna [1-3]: "); coluna = Convert.ToInt32(Console.ReadLine()) - 1; jogada++; fimJogo = conferirJogada(tabuleiro, linha, coluna, jogador, jogada); // Troca de jogador if (jogador == 1) jogador = 2; else jogador = 1; } while (!fimJogo);
imprimirTabuleiro
Esta função apenas lê a matriz e a exibe no console com formatação.
static void imprimirTabuleiro(char[,] tabuleiro) { for (int l = 0; l < 3; l++) { for (int c = 0; c < 3; c++) { Console.Write(string.Format("{0}", tabuleiro[l, c])); if (c < 2) Console.Write("|"); } Console.Write(Environment.NewLine); if (l < 2) Console.Write("-----\n"); } }
conferirJogada
Esta função recebe a jogada, altera o tabuleiro (marcando 'X' ou 'O') e verifica se houve um vencedor ou empate.
static bool conferirJogada(char[,] tabuleiro, int linha, int coluna, int jogador, int jogada) { bool trinca = false; if (jogador == 1) tabuleiro[linha, coluna] = 'X'; else tabuleiro[linha, coluna] = 'O'; // Verificar na mesma linha for (int c = 0; c < 3; c++) { if (tabuleiro[linha, c] != tabuleiro[linha, coluna]) break; if (c == 2) trinca = true; } // Verificar na mesma coluna if (!trinca) { for (int l = 0; l < 3; l++) { if (tabuleiro[l, coluna] != tabuleiro[linha, coluna]) break; if (l == 2) trinca = true; } } // Verificar na diagonal principal if (!trinca) { if (linha == coluna) { for (int cont = 0; cont < 3; cont++) { if (tabuleiro[cont, cont] != tabuleiro[linha, coluna]) break; if (cont == 2) trinca = true; } } } // Verificar na diagonal secundária if (!trinca) { if (linha + coluna == 2) { for (int cont = 0; cont < 3; cont++) { if (tabuleiro[cont, 2 - cont] != tabuleiro[linha, coluna]) break; if (cont == 2) trinca = true; } } } if (trinca) { Console.WriteLine(); imprimirTabuleiro(tabuleiro); Console.Write("JOGADOR " + jogador + " VENCEU!\n\n"); return true; } if (jogada == 9) { Console.WriteLine(); imprimirTabuleiro(tabuleiro); Console.Write("EMPATE!\n\n"); return true; } else { Console.Write("\nPRÓXIMO JOGADOR...\n\n"); return false; } }
Veja o seguinte conteúdo para melhor entendimento sobre matrizes multidimensionais: link
for
aninhado
dentro de outro.