PsySc0rpi0n Posted September 26, 2016 at 03:00 PM Report #599131 Posted September 26, 2016 at 03:00 PM Boas... Estou aqui a tentar adaptar uma função para o que pretendo fazer, mas não consigo resolver uma parte. A função verifica o tabuleiro do jogo do galo a ver se existe algum dos caracteres , X ou O, dispostos de forma a fazer os 3 em linha! Como aloquei memória para a matriz usando a forma matrix[y + x * w], em que w é o número de colunas, estou a ter dificuldades em detectar vitória quando estão os caracteres dispostos na vertical. Para o caso dos caracteres na horizontal, tenho o seguinte: if(ptabuleiro[i * 11 + 1] != '_' && ptabuleiro[i * 11 + 1] == ptabuleiro[i * 11 + DOIS] && ptabuleiro[i * 11 + 1] == ptabuleiro[i * 11 + TRES]){ printf("Mark 1\n"); return ptabuleiro[i * 11 + 1] == psim ? -1 : 1; } O DOIS e o TRES é apenas para dizer que na verdade o 2 tem que ser um 5 e o TRES tem que ser um 9, porque a matriz não é 3 * 3 mas sim 3 * 12. Isto porque eu quero que o desenho da matriz seja assim: _01_|_05_|_09_ _12_|_16_|_20_ _23_|_27_|_31_ E portanto quando o jogador insere 2 para o X, na verdade na matriz será um 5. E quando o jogador insere um 3, na verdade é um 9! Agora, não consigo fazer a verificação para as linhas verticais! Como hei-de fazer? Kurt Cobain - Grunge misses you Nissan GT-R - beast killer
HappyHippyHippo Posted September 26, 2016 at 04:18 PM Report #599134 Posted September 26, 2016 at 04:18 PM estás a misturar dados com apresentação o que quero dizer é que é má implementação usar a matriz dessa forma somente devido à apresentação, porque nao é da responsabilidade dela saber como vais apresentar-la no entanto, se pretendes então ter assim, o que deverias fazer seria: #define MATRIX_SCANLINE 11 #define MATRIX_OFFSETS(col) (col == 0 ? 1 : (col == 1 ? 5 : 9)) #define MATRIX_CELL(m, x, y) (& (m)[(y) * MATRIX_SCANLINE + MATRIX_OFFSETS(x)]) int checkHorizontal(char * matrix) { return MATRIX_CELL(matrix, 0, 0) == MATRIX_CELL(matrix, 1, 0) == MATRIX_CELL(matrix, 2, 0) || MATRIX_CELL(matrix, 0, 1) == MATRIX_CELL(matrix, 1, 1) == MATRIX_CELL(matrix, 2, 1) || MATRIX_CELL(matrix, 0, 2) == MATRIX_CELL(matrix, 1, 2) == MATRIX_CELL(matrix, 2, 2); } int checkVertical(char * matrix) { return MATRIX_CELL(matrix, 0, 0) == MATRIX_CELL(matrix, 0, 1) == MATRIX_CELL(matrix, 0, 2) || MATRIX_CELL(matrix, 1, 0) == MATRIX_CELL(matrix, 1, 1) == MATRIX_CELL(matrix, 1, 2) || MATRIX_CELL(matrix, 2, 0) == MATRIX_CELL(matrix, 2, 1) == MATRIX_CELL(matrix, 2, 2); } int checkDiagonals(char * matrix) { return MATRIX_CELL(matrix, 0, 0) == MATRIX_CELL(matrix, 1, 1) == MATRIX_CELL(matrix, 2, 2) || MATRIX_CELL(matrix, 2, 0) == MATRIX_CELL(matrix, 1, 1) == MATRIX_CELL(matrix, 0, 2); } int checkWin(char * matrix) { return checkHorizontal(matrix) || checkVertical(matrix) || checkDiagonals(matrix); } 1 Report IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
PsySc0rpi0n Posted September 26, 2016 at 05:48 PM Author Report #599139 Posted September 26, 2016 at 05:48 PM E sem aqueles defines esquisitos? Kurt Cobain - Grunge misses you Nissan GT-R - beast killer
thoga31 Posted September 26, 2016 at 07:46 PM Report #599146 Posted September 26, 2016 at 07:46 PM (edited) 1 hora atrás, PsySc0rpi0n disse: E sem aqueles defines esquisitos? Os "defines esquisitos" são macros e são uma parte importante da linguagem C. Podes passá-los a funções. Edited September 26, 2016 at 07:47 PM by thoga31 Correcção do erro ortográfico Knowledge is free!
PsySc0rpi0n Posted September 27, 2016 at 08:54 AM Author Report #599161 Posted September 27, 2016 at 08:54 AM 13 hours ago, thoga31 said: Os "defines esquisitos" são macros e são uma parte importante da linguagem C. Podes passá-los a funções. Sim, eu sei que são macros, para para mim não é fácil entendê-las! Até porque para usar isto agora desta maneira, tinha que alterar o meu código todo! Kurt Cobain - Grunge misses you Nissan GT-R - beast killer
Flinger Posted September 27, 2016 at 09:44 AM Report #599166 Posted September 27, 2016 at 09:44 AM (edited) Equivalem a um if -> else #define MATRIX_OFFSETS(col) (col == 0 ? 1 : (col == 1 ? 5 : 9)) se col == 0 entao 1 senao se col == 1 entao 5 senao 9 podes transformar isto numa função, int matrix_offsets(int col), que te devolve o índice da matriz onde tens o valor. Mas concordo com o Hippo, nem devias usar isso assim. É sempre desejável separar o mais possível a funcionalidade da interface. Edited September 27, 2016 at 09:44 AM by Flinger
PsySc0rpi0n Posted September 27, 2016 at 09:48 AM Author Report #599167 Posted September 27, 2016 at 09:48 AM Essa eu percebi... Estava a falar da outra! xD Kurt Cobain - Grunge misses you Nissan GT-R - beast killer
Flinger Posted September 27, 2016 at 10:11 AM Report #599168 Posted September 27, 2016 at 10:11 AM (edited) 😄 tinha-me passado despercebida #define MATRIX_CELL(m, x, y) (& (m)[(y) * MATRIX_SCANLINE + MATRIX_OFFSETS(x)]) aqui acedes directamente à posição da matriz. Uma matriz não passa de um array, onde gravas cada linha a seguir à outra. Ora se tens uma matriz X por Y, para aceder à posição [1][0] andas X posições para a frente. Neste caso, MATRIX_SCANLINE posições. Para acederes à posição [1][1] andas MATRIX_SCANLINE posições + 1. para aceder à posição [2] [1] acedes ao elemento [MATRIX_SCANLINE * 2 +1], etc. Expandindo a macro, com MATRIX_CELL(matrix, 2, 2) ficas com (& (matrix)[(2) * MATRIX_SCANLINE + MATRIX_OFFSETS(2)]), (& (matrix)[(2) * 11 + 9]), o que é equivalente a matrix[2][9] Edited September 27, 2016 at 10:14 AM by Flinger 1 Report
HappyHippyHippo Posted September 27, 2016 at 10:30 AM Report #599169 Posted September 27, 2016 at 10:30 AM existe um erro no código que fiz, alguém consegue descobrir qual ? dou até ao início da tarde IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
Flinger Posted September 27, 2016 at 12:37 PM Report #599171 Posted September 27, 2016 at 12:37 PM não tens por acaso o & a mais na macro MATRIX_CELL, não??? Não corri o código mas parece-me que como está estás a comparar apontadores e não os valores.
HappyHippyHippo Posted September 27, 2016 at 02:52 PM Report #599175 Posted September 27, 2016 at 02:52 PM Em 27/09/2016 às 14:37, Flinger disse: Não corri o código mas parece-me que como está estás a comparar apontadores e não os valores. sim, é isso, se bem que a remoção do & retira a funcinoalidade de atribuição de um valor ao resultado da macro function tenho uma solução engraçada (que até acho já ter demonstrado num tópico semelhante à uns anos) mas tinha renitência em apresentar-la por ser ainda mais complexa,que resolve ainda outro bug mas aqui vai : #define SPACE ' ' #define PLAYER1 'O' #define PLAYER2 'X' #define SCANLINE 11 #define OFFSETS(col) (col == 0 ? 1 : (col == 1 ? 5 : 9)) #define CELL(m, x, y) ((m)[(y) * SCANLINE + OFFSETS(x)]) int checkHorizontal(char * m) { return ((CELL(m, 0, 0) + CELL(m, 1, 0) + CELL(m, 2, 0) == CELL(m, 0, 0) * 3) && (CELL(m, 0, 0) != SPACE)) || ((CELL(m, 0, 1) + CELL(m, 1, 1) + CELL(m, 2, 1) == CELL(m, 0, 1) * 3) && (CELL(m, 0, 1) != SPACE)) || ((CELL(m, 0, 2) + CELL(m, 1, 2) + CELL(m, 2, 2) == CELL(m, 0, 2) * 3) && (CELL(m, 0, 2) != SPACE)); } int checkVertical(char * m) { return ((CELL(m, 0, 0) + CELL(m, 0, 1) + CELL(m, 0, 2) == CELL(m, 0, 0) * 3) && (CELL(m, 0, 0) != SPACE)) || ((CELL(m, 1, 0) + CELL(m, 1, 1) + CELL(m, 1, 2) == CELL(m, 1, 0) * 3) && (CELL(m, 1, 0) != SPACE)) || ((CELL(m, 2, 0) + CELL(m, 2, 1) + CELL(m, 2, 2) == CELL(m, 2, 0) * 3) && (CELL(m, 2, 0) != SPACE)); } int checkDiagonals(char * m) { return ((CELL(m, 0, 0) + CELL(m, 1, 1) + CELL(m, 2, 2) == CELL(m, 0, 0) * 3) && (CELL(m, 0, 0) != SPACE)) || ((CELL(m, 2, 0) + CELL(m, 1, 1) + CELL(m, 0, 2) == CELL(m, 0, 0) * 3) && (CELL(m, 2, 0) != SPACE)); } int checkWin(char * m) { return checkHorizontal(m) || checkVertical(m) || checkDiagonals(m); } int validCheck() { return PLAYER1 != PLAYER2 + SPACE && PLAYER2 != PLAYER1 + SPACE; } int main(void) { char m[SCANLINE * 3]; memset(m, ' ', SCANLINE * 3); if (!validCheck()) { printf("invalid check code for the selected tokens"); } return 0; } 1 Report IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
seuqram Posted September 27, 2016 at 06:54 PM Report #599181 Posted September 27, 2016 at 06:54 PM (edited) I love your way of coding :] Porque é que o array vai de index 4 a 4? Têm a ver com algum problema que envolva conversões de array de chars para array de inteiros e vice-versa? Acrescento isto na função validCheck: bool validCheck() { for(int i = 0; i < 3; i++) { if(PLAYER1 == PLAYER2 * i + SPACE * (2 - i) || PLAYER2 == PLAYER1 * i + SPACE * (2 - i))return false; } return true; } Edited September 27, 2016 at 08:13 PM by seuqram
PsySc0rpi0n Posted September 28, 2016 at 06:53 AM Author Report #599184 Posted September 28, 2016 at 06:53 AM Isso é tudo muito lindo, mas não me estou a ver a alterar o que já tenho para incluir isto tudo! Queria mesmo era usar a forma como eu estava a fazer originalmente para poder continuar com o que tenho! Senão assim, já sei que a coisa morre por aqui! Kurt Cobain - Grunge misses you Nissan GT-R - beast killer
Flinger Posted September 28, 2016 at 08:02 AM Report #599186 Posted September 28, 2016 at 08:02 AM (edited) Não conseguiste com o código do Hippo? É só substituíres as macros pela tua estrutura. partindo do princípio que também definiste "UM" como 1, para manter a coerência int checkVertical(char * matrix) { return pTabuleiro[0 * 12 + UM] == pTabuleiro[1 * 12 + UM] == pTabuleiro[2 * 12 + UM] != '_' || pTabuleiro[0 * 12 + DOIS] == pTabuleiro[1 * 12 + DOIS] == pTabuleiro[2 * 12 + DOIS] != '_' || pTabuleiro[0 * 12 + TRES] == pTabuleiro[1 * 12 + TRES] == pTabuleiro[2 * 12 + TRES] != '_' } Edited September 28, 2016 at 08:04 AM by Flinger Adicionada verificação se não estão em branco
PsySc0rpi0n Posted September 28, 2016 at 09:30 AM Author Report #599190 Posted September 28, 2016 at 09:30 AM (edited) Ok, mas e porquê 12??? Eu tenho usado 11. Não percebi bem o 12. E com esse código, o loop que ue tenho não faz sentido. Mas preciso dele para as horizontais, certo? Edited September 28, 2016 at 09:31 AM by PsySc0rpi0n Kurt Cobain - Grunge misses you Nissan GT-R - beast killer
Flinger Posted September 28, 2016 at 09:40 AM Report #599191 Posted September 28, 2016 at 09:40 AM (edited) Desculpa é 11... Fiz de cabeça, pareceu-me que tinha visto que o comprimento da linha era 12. Para a horizontal podes fazer igual a este, mas fixando a linha. Não faz muito sentido fazeres um loop para 3 posições, até porque o compilador vai provavelmente optimizar o código retirando o loop. Edited September 28, 2016 at 09:44 AM by Flinger
PsySc0rpi0n Posted September 28, 2016 at 10:02 AM Author Report #599192 Posted September 28, 2016 at 10:02 AM E ainda outro pormenor. Isso vai retornar 0 ou 1. No entanto eu estava a devovler o -1 e o 1 que usava para identificar o jogador e devolvia 0 para o caso de empate e devolvia -2 caso ainda houvesse posições vazias! Com esse código terei que reformular a função para manter as mesmas funcionalidades. Kurt Cobain - Grunge misses you Nissan GT-R - beast killer
Flinger Posted September 28, 2016 at 10:40 AM Report #599193 Posted September 28, 2016 at 10:40 AM (edited) ou então refazes estas funções, como: int checkVertical(char * matrix) { int res= pTabuleiro[0 * 12 + UM] == pTabuleiro[1 * 12 + UM] == pTabuleiro[2 * 12 + UM] != '_' || pTabuleiro[0 * 12 + DOIS] == pTabuleiro[1 * 12 + DOIS] == pTabuleiro[2 * 12 + DOIS] != '_' || pTabuleiro[0 * 12 + TRES] == pTabuleiro[1 * 12 + TRES] == pTabuleiro[2 * 12 + TRES] != '_' if (!res) return -1; else return 1; } Edited September 28, 2016 at 10:41 AM by Flinger
PsySc0rpi0n Posted September 28, 2016 at 10:56 AM Author Report #599194 Posted September 28, 2016 at 10:56 AM Ok, vou ver se consigo pôr isso a funcionar! Mas só depois de fazer um trabalho que aqui tenho! Sim, eu estou no meu trabalho! E fazer um programa par ajogar o ic tac toe não é o meu trabalho! xD Kurt Cobain - Grunge misses you Nissan GT-R - beast killer
HappyHippyHippo Posted September 28, 2016 at 01:09 PM Report #599201 Posted September 28, 2016 at 01:09 PM (edited) prontos ... se tens esses requisitos todos: int checkHorizontal(char * m) { // para todas as linhas for (int line = 1; line < 3; ++line) { // verificar linha "line" if ( pTabuleiro[line * 11 + UM] == pTabuleiro[line * 11 + DOIS] && pTabuleiro[line * 11 + UM] == pTabuleiro[line * 11 + TRES] && pTabuleiro[line * 11 + UM] != '_') // retornar o valor associado ao vencedor return pTabuleiro[line * 11 + UM] == 'O' : -1 : 1; } return 0; } int checkVertical(char * m) { // para todas as colunas for (int column = UM; column <= TRES; ) { // verificar coluna "column" if ( pTabuleiro[0 * 11 + column] == pTabuleiro[1 * 11 + column] && pTabuleiro[0 * 11 + column] == pTabuleiro[2 * 11 + column] && pTabuleiro[0 * 11 + column] != '_') // retornar o valor associado ao vencedor return pTabuleiro[0 * 11 + column] == 'O' : -1 : 1; // incremneto do ciclo de coluna column = column == UM ? DOIS : (column == DOIS ? TRES : TRES + 1); } return 0; } int checkDiagonals(char * m) { // verificar diagonal principal if ( pTabuleiro[0 * 11 + UM] == pTabuleiro[1 * 11 + DOIS] && pTabuleiro[0 * 11 + UM] == pTabuleiro[2 * 11 + TRES] && pTabuleiro[0 * 11 + UM] != '_') // retornar o valor associado ao vencedor return pTabuleiro[0 * 11 + column] == 'O' : -1 : 1; // verificar diagonal secundaria if ( pTabuleiro[2 * 11 + UM] == pTabuleiro[1 * 11 + DOIS] && pTabuleiro[2 * 11 + UM] == pTabuleiro[0 * 11 + TRES] && pTabuleiro[2 * 11 + UM] != '_') // retornar o valor associado ao vencedor return pTabuleiro[0 * 11 + column] == 'O' : -1 : 1; return 0; } int checkWin(char * m) { // verificar vencedor int check = checkHorizontal(m) || checkVertical(m) || checkDiagonals(m); if (check) return check; // verificar se existem espaços vazios for (int line; line < 3; ++line) { for (int column; column <= TRES; ) { // verificar se a célula iterada se encontra vazia if (pTabuleiro[line * 11 + column] == '_') return -2; // incremneto do ciclo de coluna column = column == UM ? DOIS : (column == DOIS ? TRES : TRES + 1); } } // empate ... return 0; } Edited September 28, 2016 at 01:10 PM by HappyHippyHippo removed unacessary code IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now