Крестики-нолики: критика кода - C (СИ)

Узнай цену своей работы

Формулировка задачи:

В качестве практики, написал консольные крестики-нолики. Хотелось бы услышать мнение опытных людей. Над чем стоит поработать? Что в коде "не так"?
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
 
struct coordinates{int x; int y;};
 
void manual()
{
    printf("*******************************\n");
    printf("W/S/A/D - choose cell\n");
    printf("Space - put X/O\n");
    printf("Esc - exit\n");
    printf("*******************************\n");
    printf("Press any key to start...\n");
}
 
void initCellCoordinates(struct coordinates *cellCoord, int index)
{
    int i=0,cellX,cellY;
 
    for(cellY=1;cellY<=17;cellY+=8)
    {
        for(cellX=1;cellX<=21;cellX+=10)
        {
            cellCoord[i].x=cellX;
            cellCoord[i].y=cellY;
            i++;
        }
    }
    return;
}
 
void initMatrix(char *matrix, int y, int x)
{
    int i,j;
 
    for(i=0;i<x;i++)
    {
        for(j=0;j<y;j++)
        {
            *(matrix + i*y + j)='0';
        }
    }
    return;
}
 
void initGrMatrix(char *matrix, int y, int x)
{
    int i,j;
 
    for(i=0;i<y;i++)
    {
        for(j=0;j<x;j++)
        {
            if(i==0 || i==8 || i==16 || i==24)
            {
                if(j==0 || j==10 || j==20 || j==30)
                    *(matrix + i*x + j)='+';
                else *(matrix + i*x + j)= '-';
            }
            else if(j==0 || j==10 || j==20 || j==30)
                *(matrix + i*x + j)='|';
            else *(matrix + i*x + j) = ' ';
        }
    }
    return;
}
 
void printMatrix(char *matrix, int y, int x)
{
    int i,j;
 
    for(i=0;i<y;i++)
    {
        for(j=0;j<x;j++)
        {
            printf("%c", *(matrix + i*x + j));
        }
        printf("\n");
    }
    return;
}
 
void moveFrame(char *matrix, int my, int mx, struct coordinates *frameCoord, struct coordinates *cellCoord, struct coordinates *lastFrameCoord)
{
 
    *(matrix + cellCoord[frameCoord->y * 3 + frameCoord->x].y * mx + cellCoord[frameCoord->y * 3 + (frameCoord->x)].x)='#';
    *(matrix + cellCoord[lastFrameCoord->y * 3 + lastFrameCoord->x].y * mx + cellCoord[lastFrameCoord->y * 3 + lastFrameCoord->x].x)=' ';
 
    return;
}
 
void addPlayerSymbol(char *checkMatrix, char *grMatrix, int gmX, struct coordinates *frameCoord, struct coordinates *cellCoord, char *player, char *paternX, char *paternO)
{
    int i,j;
 
    switch(*player)
    {
        case 'X':
            for(i=0;i<5;i++)
            {
                for(j=0;j<5;j++)
                {
                    *(grMatrix + (cellCoord[frameCoord->y * 3 + frameCoord->x].y+1+i) * gmX + cellCoord[frameCoord->y * 3 + (frameCoord->x)].x+2+j) = *(paternX + i*5 + j);
                }
            }
            return;
        case 'O':
            for(i=0;i<5;i++)
            {
                for(j=0;j<5;j++)
                {
                    *(grMatrix + (cellCoord[frameCoord->y * 3 + frameCoord->x].y+1+i) * gmX + cellCoord[frameCoord->y * 3 + (frameCoord->x)].x+2+j) = *(paternO + i*5 + j);
                }
            }
            return;
        default:
            return;
    }
}
 
void changePlayer(char *player)
{
    if((*player)=='X')
        (*player)='O';
    else
        (*player)='X';
    return;
}
 
int control(struct coordinates *frameCoord, struct coordinates *lastFrameCoord, char *checkMatrix,int cmY,int cmX, char *player, int *quit)
{
    //return 0 - ничего не делать; return 1 - передвинуть #(frame); return 2 - ввести символ Х/О
    switch(getch())
    {
        case 'w':
            if(frameCoord->y > 0)
            {
                lastFrameCoord->x=frameCoord->x;
                lastFrameCoord->y=frameCoord->y;
                frameCoord->y--;
                return 1;   
            }
            else
                return 0;
        case 's':
            if(frameCoord->y < 2)
            {
                lastFrameCoord->x=frameCoord->x;
                lastFrameCoord->y=frameCoord->y;
                frameCoord->y++;
                return 1;
            }
            else
                return 0;
        case 'a':
            if(frameCoord->x > 0)
            {
                lastFrameCoord->x=frameCoord->x;
                lastFrameCoord->y=frameCoord->y;
                frameCoord->x--;
                return 1;   
            }
            else
                return 0;
        case 'd':
            if(frameCoord->x < 2)
            {
                lastFrameCoord->x=frameCoord->x;
                lastFrameCoord->y=frameCoord->y;
                frameCoord->x++;
                return 1;
            }
            else
                return 0;
        case 32/*space*/:
            if(*(checkMatrix + frameCoord->y * cmX + frameCoord->x)=='0')
            {
                *(checkMatrix + frameCoord->y * cmX + frameCoord->x)=*player;
                return 2;
            }
            else
                return 0;
        case 27/*ESC*/:
            *quit=1;
            return;
 
    }
}
 
int check(char *checkMatrix, int cmX, char *winner)
{
    int i,j;
 
    if(!(*(checkMatrix + 0*cmX + 0)=='0') && *(checkMatrix + 0*cmX + 0)==*(checkMatrix + 0*cmX + 1) && *(checkMatrix + 0*cmX + 0)==*(checkMatrix + 0*cmX + 2))//первая строчка(1)
    {
        *winner=*(checkMatrix + 0*cmX + 0);
        return 1;
    }
    else if(!(*(checkMatrix + 1*cmX + 0)=='0') && *(checkMatrix + 1*cmX + 0)==*(checkMatrix + 1*cmX + 1) && *(checkMatrix + 1*cmX + 0)==*(checkMatrix + 1*cmX + 2))//вторая строчка(2)
    {
        *winner=*(checkMatrix + 1*cmX + 0);
        return 2;
    }
    else if(!(*(checkMatrix + 2*cmX + 0)=='0') && *(checkMatrix + 2*cmX + 0)==*(checkMatrix + 2*cmX + 1) && *(checkMatrix + 2*cmX + 0)==*(checkMatrix + 2*cmX + 2))//третья строчка(3)
    {
        *winner=*(checkMatrix + 2*cmX + 0);
        return 3;
    }
    else if(!(*(checkMatrix + 0*cmX + 0)=='0') && *(checkMatrix + 0*cmX + 0)==*(checkMatrix + 1*cmX + 0) && *(checkMatrix + 0*cmX + 0)==*(checkMatrix + 2*cmX + 0))//первый столбец(4)
    {
        *winner=*(checkMatrix + 0*cmX + 0);
        return 4;
    }
    else if(!(*(checkMatrix + 0*cmX + 1)=='0') && *(checkMatrix + 0*cmX + 1)==*(checkMatrix + 1*cmX + 1) && *(checkMatrix + 0*cmX + 1)==*(checkMatrix + 2*cmX + 1))//второй столбец(5)
    {
        *winner=*(checkMatrix + 0*cmX + 1);
        return 5;
    }
    else if(!(*(checkMatrix + 0*cmX + 2)=='0') && *(checkMatrix + 0*cmX + 2)==*(checkMatrix + 1*cmX + 2) && *(checkMatrix + 0*cmX + 2)==*(checkMatrix + 2*cmX + 2))//третий столбец(6)
    {
        *winner=*(checkMatrix + 0*cmX + 2);
        return 6;
    }
    else if(!(*(checkMatrix + 0*cmX + 0)=='0') && *(checkMatrix + 0*cmX + 0)==*(checkMatrix + 1*cmX + 1) && *(checkMatrix + 0*cmX + 0)==*(checkMatrix + 2*cmX + 2))//первая диагональ(7)
    {
        *winner=*(checkMatrix + 0*cmX + 0);
        return 7;
    }
    else if(!(*(checkMatrix + 2*cmX + 0)=='0') && *(checkMatrix + 2*cmX + 0)==*(checkMatrix + 1*cmX + 1) && *(checkMatrix + 2*cmX + 0)==*(checkMatrix + 0*cmX + 2))//вторая диагональ(8)
    {
        *winner=*(checkMatrix + 2*cmX + 0);
        return 8;
    }
    else //если нет пустых клеток возвращать 9
        for(i=0;i<3;i++)
        {
            for(j=0;j<3;j++)
            {
                if(*(checkMatrix + i*cmX + j)=='0')
                    return 0;
            }
        }
        return 9;
}
 
void putWinLine(char *grMatrix, int gmX, int *winLine)
{
    int i,j;
    switch(*winLine)
    {
        case 1:
            for(i=0;i<27;i++)
            {
                *(grMatrix + 4*gmX + 2+i)='o';
            }
            return;
        case 2:
            for(i=0;i<27;i++)
            {
                *(grMatrix + 12*gmX + 2+i)='o';
            }
            return;
        case 3:
            for(i=0;i<27;i++)
            {
                *(grMatrix + 20*gmX + 2+i)='o';
            }
            return;
        case 4:
            for(i=0;i<23;i++)
            {
                *(grMatrix + (i+1)*gmX + 5)='o';
            }
            return;
        case 5:
            for(i=0;i<23;i++)
            {
                *(grMatrix + (i+1)*gmX+ + 15)='o';
            }
            return;
        case 6:
            for(i=0;i<23;i++)
            {
                *(grMatrix + (i+1)*gmX+2 + 23)='o';
            }
            return;
    }
}
 
void addWins(int *winsX, int *winsO, char *winner)
{
    switch(*winner)
    {
        case 'X':
            (*winsX)++;
            (*winner)='0';
            break;
        case 'O':
            (*winsO)++;
            (*winner)='0';
            break;
        default:
            (*winner)='0';
    }
    *winsX++;
    return;
}
 
void printWins(int *winsX, int *winsO)
{
    printf("             Wins\n");
    printf("         X:%d     O:%d\n", *winsX, *winsO);
    printf("===============================\n");
    return;
}
 
//******************************************************** Main **************************************************
void main()
{
    system("mode con cols=32 lines=36");
    system("title TicTacToe");
 
    int winLine=0, quit=0, winsX=0, winsO=0;
    struct coordinates frameCoord, lastFrameCoord, cellCoord[9];
    char grMatrix[25][31],
        checkMatrix[3][3],
        player='X',
        winner='0',
        paternX[5][5]={
                            {'*',' ',' ',' ','*'},
                            {' ','*',' ','*',' '},
                            {' ',' ','*',' ',' '},
                            {' ','*',' ','*',' '},
                            {'*',' ',' ',' ','*'}
                        },
        paternO[5][5]={
                            {' ','*','*','*',' '},
                            {'*',' ',' ',' ','*'},
                            {'*',' ',' ',' ','*'},
                            {'*',' ',' ',' ','*'},
                            {' ','*','*','*',' '}
                        };
 
    initCellCoordinates(cellCoord, 9);
    frameCoord.x=0;
    frameCoord.y=0;
 
    manual();
    while(quit==0)
    {
        initGrMatrix(&grMatrix[0][0],25,31);
        initMatrix(&checkMatrix[0][0],3,3);
 
        getch();
        grMatrix[cellCoord[frameCoord.y * 3 + frameCoord.x].y][cellCoord[frameCoord.y * 3 + (frameCoord.x)].x]='#';
        system("cls");
        printWins(&winsX, &winsO);
        printMatrix(&grMatrix[0][0],25,31);
        printf("===============================\n");
        printf("Your move, %c.\n\n", player);
 
        while(check(&checkMatrix[0][0], 3, &winner)==0)
        {
            switch(control(&frameCoord, &lastFrameCoord, &checkMatrix[0][0],3,3, &player, &quit))
            {
                case 1://передвинуть #
                    moveFrame(&grMatrix[0][0],25,31, &frameCoord, cellCoord, &lastFrameCoord);
                    system("cls");
                    printWins(&winsX, &winsO);
                    printMatrix(&grMatrix[0][0],25,31);
                    printf("===============================\n");
                    printf("Your move, %c.\n\n", player);
                    break;
                case 2: //нарисовать Х/О
                    addPlayerSymbol(&checkMatrix[0][0], &grMatrix[0][0], 31, &frameCoord, cellCoord, &player, &paternX[0][0], &paternO[0][0]);
                    changePlayer(&player);
                    system("cls");
                    printWins(&winsX, &winsO);
                    printMatrix(&grMatrix[0][0],25,31);
                    printf("===============================\n");
                    printf("Your move, %c.\n\n", player);
                    break;
                case 0:
                    break;
            }
            if(quit==1)
                break;
        }
 
        winLine=check(&checkMatrix[0][0], 3, &winner);
        putWinLine(&grMatrix[0][0], 31, &winLine);
        system("cls");
        printWins(&winsX, &winsO);
        printMatrix(&grMatrix[0][0],25,31);
        printf("===============================\n");

        if(winLine!=9)
            printf("Winner: %c\n", winner);
        else
            printf("No empty cells\n");
        addWins(&winsX, &winsO, &winner);
        printf("\n\n");
        printf("Press any key to continue");
    }
    return;
}

Решение задачи: «Крестики-нолики: критика кода»

textual
Листинг программы
#define MAX_Y 17 
#define MAX_X 21
...
//etc

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

8   голосов , оценка 3.5 из 5