车运动功能没有发现中断

时间:2015-10-22 10:40:16

标签: c++ collision chess interruption

我正在尝试编写一个功能,检查黑色国王是否被白车检查。当我试图搜索车和国王之间是否有任何碎片时,就会出现问题。

    void rook_white(piece A[])                                      // does WR check BK
{
    cout << "Found White Rook ";
    int k_x;                                                  // BK'S x coordinate
    int k_y;                                                  // BK's y coordinate
    bool check = false;
    for(int x=0; x<8; x++)
    {
        for(int y=0; y<8; y++)
        {
            if(A[t_i].field[m_x-x][m_y] == 'k')                 // Moving Left
            {
                k_x=m_x;
                k_y=m_y;
                goto al_1;
            }
        }
    }
    for(int x=0; x<8; x++)
    {
        for(int y=0; y<8; y++)
        {
            if(A[t_i].field[m_x+x][m_y] == 'k')                 // Moving Right
            {
                k_x=m_x;
                k_y=m_y;
                goto al_2;
            }
        }
    }
    for(int x=0; x<8; x++)
    {
        for(int y=0; y<8; y++)
        {
            if(A[t_i].field[m_x][m_y-y] == 'k')                 // Moving Up
            {
                k_x=m_x;
                k_y=m_y;
                goto al_3;
            }
        }
    }
    for(int x=0; x<8; x++)
    {
        for(int y=0; y<8; y++)
        {
            if(A[t_i].field[m_x][m_y+y] == 'k')                 // Moving Down
            {
                k_x=m_x;
                k_y=m_y;
                goto al_4;
            }
        }
    }
al_1:
    for(int x=0; x<k_x; x++)
    {
        for(int y=0; y<k_y; y++)
        {
            if(!A[t_i].field[m_x-x][m_y] == '*')                   // Checking left
            {
                goto loop_exit;
            }
        }
    }
al_2:
    for(int x=0; x<k_x; x++)
    {
        for(int y=0; y<k_y; y++)
        {
            if(!A[t_i].field[m_x+x][m_y] == '*')                    // Checking Right
            {
                goto loop_exit;
            }
        }
    }
al_3:
    for(int x=0; x<k_x; x++)
    {
        for(int y=0; y<k_y; y++)
        {
            if(!A[t_i].field[m_x][m_y-y] == '*')                    // Checking Up
            {
                goto loop_exit;
            }
        }
    }
al_4:
    for(int x=0; x<k_x; x++)
    {
        for(int y=0; y<k_y; y++)
        {
            if(!A[t_i].field[m_x][m_y+y] == '*')                    // Checking Down
            {
                goto loop_exit;
            }
        }
    }
loop_exit:
    check = false;
    if (check == true)
    {
        ofstream fr(FVR,ios::app);
        fr << "Black is in check by rook " << t_i << endl;
    }
}

该功能搜索x和y轴上的王位置。然后它转到一个特定的算法(al_1,al_2,...),在其中搜索国王和车之间是否有任何东西。

输入文件就是这样的:

********
***k****
********
***q****
********
********
***R****
********

这不应该输出任何内容,而

********
***k****
********
********
********
********
***R****
********

应该输出“Black is in check in rook”。 (t_i是正在检查的董事会的编号)

A [t_i]是一个struct数组,struct pieces由char字段[8] [8]组成。

我使用结构,因为我必须检查无限数量的板。

k_x和k_y是国王坐标。 m_x和m_y是从搜索函数传输的全局变量

这是程序本身的int main()

#include <iostream>
#include <fstream>                  // chess
#include <cstdlib>
using namespace std;                                                       // PROGRAM CHECKS FOR CHESS CHEKS
const char FVD[]="5_input.txt";                                 // **************************************************
const char FVR[]="5_output.txt";                                // P - white pawn   (WP)      p - black pawn     (BP)
//---                                                           // R - white rook   (WR)      r - black rook     (BR)
//---                                                           // B - white bishop (WB)      b - black bishop   (BB)
int m_i=0;          // max i                                    // N - white knight (WN)      n - black knight   (BN)
int m_x=0;          //                                          // Q - white queen  (WQ)      q - black queen    (BQ)
int m_y=0;          //                                          // K - white king   (WK)      k - black king     (BK)
int t_i=0;          //                                          // **************************************************
struct piece
{
    char field[8][8];
};
void read(piece A[])
{
    ifstream fd(FVD);
    int i=0;
    m_i=0;
    while(!fd.eof())
    {
        for(int x=0; x<8; x++)
        {
            for(int y=0; y<8; y++)
            {
                fd >> A[i].field[x][y];
            }
        }
        fd.ignore();
        i++;
        m_i=i;
    }
    fd.close();
}
///  ----------------------------------------------BLACK KING IS IN CHECK--------------------------------------------------------------
void rook_white(piece A[])                                      // does WR check BK
{
    cout << "Found White Rook ";
    int k_x;                                                  // BK'S x coordinate
    int k_y;                                                  // BK's y coordinate
    bool check = false;
    for(int x=0; x<8; x++)
    {
        for(int y=0; y<8; y++)
        {
            if(A[t_i].field[m_x-x][m_y] == 'k')                 // Moving Left
            {
                k_x=m_x;
                k_y=m_y;
                goto al_1;
            }
        }
    }
    for(int x=0; x<8; x++)
    {
        for(int y=0; y<8; y++)
        {
            if(A[t_i].field[m_x+x][m_y] == 'k')                 // Moving Right
            {
                k_x=m_x;
                k_y=m_y;
                goto al_2;
            }
        }
    }
    for(int x=0; x<8; x++)
    {
        for(int y=0; y<8; y++)
        {
            if(A[t_i].field[m_x][m_y-y] == 'k')                 // Moving Up
            {
                k_x=m_x;
                k_y=m_y;
                goto al_3;
            }
        }
    }
    for(int x=0; x<8; x++)
    {
        for(int y=0; y<8; y++)
        {
            if(A[t_i].field[m_x][m_y+y] == 'k')                 // Moving Down
            {
                k_x=m_x;
                k_y=m_y;
                goto al_4;
            }
        }
    }
al_1:
    for(int x=0; x<k_x; x++)
    {
        for(int y=0; y<k_y; y++)
        {
            if(!A[t_i].field[m_x-x][m_y] == '*')                   // Checking left
            {
                goto loop_exit;
            }
        }
    }
al_2:
    for(int x=0; x<k_x; x++)
    {
        for(int y=0; y<k_y; y++)
        {
            if(!A[t_i].field[m_x+x][m_y] == '*')                    // Checking Right
            {
                goto loop_exit;
            }
        }
    }
al_3:
    for(int x=0; x<k_x; x++)
    {
        for(int y=0; y<k_y; y++)
        {
            if(!A[t_i].field[m_x][m_y-y] == '*')                    // Checking Up
            {
                goto loop_exit;
            }
        }
    }
al_4:
    for(int x=0; x<k_x; x++)
    {
        for(int y=0; y<k_y; y++)
        {
            if(!A[t_i].field[m_x][m_y+y] == '*')                    // Checking Down
            {
                goto loop_exit;
            }
        }
    }
loop_exit:
    check = false;
    if (check == true)
    {
        ofstream fr(FVR,ios::app);
        fr << "Black is in check by rook " << t_i << endl;
    }
}
///-----------------------------------------SEARCHING FOR THE CHECKS // CALLING FUNCTIONS --------------------------------------------
void search(piece A[])                                               // searches for piece and calls a function related to it
{
    for(int i=0; i<m_i-1; i++)
    {
        for(int x=0; x<8; x++)
        {
            for(int y=0; y<8; y++)
            {
        if (A[i].field[x][y]=='R')
                {
                    t_i=i;
                    m_x=x;
                    m_y=y;
                    rook_white(A);
                }

            }
        }
    }
}
int main()
{
    piece A[10];
    remove(FVR);            // clears the output before inputting new data because of ios::app
    read(A);
    search(A);
    ofstream fr(FVR);
    fr << "Done";
    return 0;
}

1 个答案:

答案 0 :(得分:4)

我会做我不常做的事情 - 我会给你一个完整的往返行程(因为我觉得这样)。

你开始使用的main()应该读取任意数量的字段(但实际上是11日崩溃),以及search()函数,它最终会遍历所有可能的棋子。但是你的程序在检查第一件白色车时失败了。

你也从C开始,然后介绍顺势疗法剂量的C ++,实际上使事情变得更加困难。

所以让我们减少它。 首先,我们将获得&#34; minimal&#34;进入示例代码。

让我们使用<vector>而不是二维数组。向量是 在C ++中最有用的东西之一,并且几乎没有理由再使用C风格的数组(除了C API兼容性之外)。

#include <vector>
#include <iostream>

typedef std::vector< std::vector< char > > Field;

Field现在是char s向量向量的别名。这与二维数组(包括[][]寻址)基本相同,但它很快就会有一些优势。

您的rook_white()(正如您设计的那样)需要一个字段,以及车辆的X和Y坐标。请允许我稍微调整你的函数原型 - 我喜欢更具表现力的标识符名称

void rook_white( Field const & field, unsigned rook_x, unsigned rook_y );

搜索并删除A[t_i].,我们目前只处理该字段。使用m_xrook_x m_y搜索并替换rook_y。不是太难。也替换:

        ofstream fr(FVR,ios::app);
        fr << "Black is in check by rook " << t_i << endl;

使用:

        std::cout << "Black is in check by rook" endl;

现在我们不用担心文件I / O.

现在,我们需要设置一个字段,但我们现在需要从文件中读取它。实际检查完成后,您可以扩展代码。

int main()
{
    Field field( 8, std::vector< char >( 8, '*' ) );

std::vector< char >( 8, '*' )创建一个8 '8'个字符的临时向量。 Field field( 8, /*...*/ );创建一个Field,由8个临时向量副本组成。

现在让我们放置你的作品。

    unsigned rook_x = 3;
    unsigned rook_y = 6;
    field[rook_x][rook_y] = 'R';

    unsigned king_x = 3;
    unsigned king_y = 1;
    field[king_x][king_y] = 'k';

此时我意识到你的示例代码得到了&#34; X&#34;和&#34; Y&#34;坐标在search() 中混淆(在X = 6,Y = 3时报告车辆),但没关系。这不是你问题的根源。

我们现在有字段和坐标来调用你的函数。

    rook_white( field, rook_x, rook_y );
    return 0;
}

这种编写main()并不能真正反映最终应用程序应该执行的操作的方式,而是针对特定功能设置测试,称为测试驱动程序。我们只是从你的例子中删除了50多行不必要的代码,消除了各种不相关的潜在问题。

现在,让我们看一下rook_white(),不管吗?

因为我们现在有vector< vector< char > >而不是&#34; dumb&#34;数组,我们可以做一些漂亮的事情:用[]替换.at()访问权限。原因?如果[]的索引超出范围,则可能会也可能不会使程序崩溃。如果.at()的索引超出范围,抛出异常。

所以,虽然.at()有点慢(通常不会在生产代码中使用),但我建议初学者使用它,因为它不允许错误&#34;隐藏&#34;。

此时你应该挑起眉毛,自己思考,&#34;他为什么要这样做?&#34;。然后你应该看看你的循环,然后......

for(int x=0; x<8; x++)
{
    for(int y=0; y<8; y++)
    {
        if(field[rook_x-x][rook_y] == 'k')
        {
            k_x=rook_x;
            k_y=rook_y;
            goto al_1;
        }
    }
}

是的,确切地说。你有越界访问到你的领域。

rook_x / rook_y位于该领域的某个地方,但如果找不到国王,你仍坚持要访问[rook_x - 7][rook_y]以外的任何内容。这是原始代码中的负面索引。由于我将坐标更改为unsigned(相反溢出并变为非常大),您将遇到段错误(如果您很幸运)。那实际上是无意的;我只是通过habbit宣布不能为负unsigned的内容。

但这就是为什么我建议在您还在学习的同时使用vector<>的{​​{1}}方法:尽可能早地和尽可能地失败。 异常优于未定义的行为。

此外,您(在所有这些循环中)始终循环遍历.at() x,但仅使用 one < / em>中的两个变量循环中。这有很多浪费的时钟周期。这不会打破你的逻辑只是机会...

此时您可能希望完全重新编写代码。但等等,还有更多。

如果你&#34;向左移动&#34;在你的第一个循环中,找到那里的王,你y。在那里你循环(再次使用两个循环计数器中的一个)来检查干预部分。

第一个循环是goto al_1,检查x == 0 ......好好猜测,你发现白车要介入,因为没有{{1在该字段中,您跳转到[rook_x - 0][rook_y] ...

即使你不会犯这个错误,你也会走出那个循环并进入'*',同时检查所有剩余的方向

即使一切都不会发生,无论发生什么,你最终都会碰到这个:

loop_exit

嗯, al_2永远不会发生,对吗?

此时我引用你的一条评论......

  

......我只是不理解[转换语句]并且无法真正理解如何将它们写为开关。

我的建议?我完全理解你为什么要写一些真实的东西&#34;尽可能快地。教科书很无聊。但你真的应该花更多的时间和#34;包裹你的头脑#34;基本概念。 C和C ++是一种非常适用于&#34;试用版和C&C的语言。错误&#34;接近来学习它们。有太多可能,而且会出错。

We have a list of recommended textbooks, if the one you have isn't to your tastes.

如果你在真正掌握了基本知识之前尝试了太大的东西(比如国际象棋程序),你可能会遇到的任何问题的答案最终会比舒适的时间长得多,无论是写作(如果有人感觉到的话)喜欢它,并为你消化。

请:

不要使用loop_exit: check = false; if (check == true) { std::cout << "Black is in check by rook \n"; } ,除非你绝对,积极地知道自己在做什么。