C # se affermazioni

1

Attualmente sto lavorando a un gioco di dama C # per un progetto universitario in programmazione. Ma sono arrivato al punto in cui ho bisogno di verificare se un pezzo può essere spostato, o saltare, ma sento che sto usando un sacco di codice che non è necessario per ottenere risposte vere o false.

if (arrayX == 0)
{
    if (board.GetBoard(arrayX + 1, arrayY - 1).Piece == null)
    {
        return true;
    }
}
else if (arrayX == 7)
{
    if (board.GetBoard(arrayX - 1, arrayY - 1).Piece == null)
    {
        return true;
    }
}

Ad esempio, c'è un modo più efficiente di fare queste istruzioni if? Nel codice ho più se affermazioni che separano altre affermazioni if. Quindi, in sintesi, c'è un modo per controllare carichi di parametri, in modo efficiente, senza usare un sacco di istruzioni if che si ramificano l'una sull'altra?

    
posta iBaconButty 10.02.2015 - 00:20
fonte

3 risposte

3

Puoi iniziare creando un metodo all'interno della classe Board che rende il tuo codice leggermente più breve:

public class Board()
{
    public bool IsPieceMissing(x, y)
    {
        return this.GetBoard(x, y).Piece == null;
    }
}

...

if (arrayX == 0)
{
    if (board.IsPieceMissing(arrayX + 1, arrayY - 1))
    {
        return true;
    }
}
else if (arrayX == 7)
{
    if (board.IsPieceMissing(arrayX - 1, arrayY - 1))
    {
        return true;
    }
}

La prossima cosa è lavorare sulla logica del business, ma per questo, è necessario fornire un quadro più globale. Qual è il corpo completo del metodo? Alla fine restituisce false ? Supponendo che contenga solo la parte che hai già fornito e il return false; alla fine, in questo modo:

private bool DoSomething(arrayX, arrayY)
{
    if (arrayX == 0)
    {
        if (board.IsPieceMissing(arrayX + 1, arrayY - 1))
        {
            return true;
        }
    }
    else if (arrayX == 7)
    {
        if (board.IsPieceMissing(arrayX - 1, arrayY - 1))
        {
            return true;
        }
    }

    return false;
}

puoi tornare immediatamente invece di aspettare fino alla fine. Il metodo diventa:

private bool DoSomething(arrayX, arrayY)
{
    if (arrayX == 0)
    {
        return board.IsPieceMissing(arrayX + 1, arrayY - 1);
    }
    else if (arrayX == 7)
    {
        return board.IsPieceMissing(arrayX - 1, arrayY - 1);
    }

    return false;
}

Poiché la prima condizione restituisce ora qualcosa, non è necessario else :

private bool DoSomething(arrayX, arrayY)
{
    if (arrayX == 0)
    {
        return board.IsPieceMissing(arrayX + 1, arrayY - 1);
    }

    if (arrayX == 7)
    {
        return board.IsPieceMissing(arrayX - 1, arrayY - 1);
    }

    return false;
}
    
risposta data 10.02.2015 - 00:40
fonte
1

Ho esaminato il tuo codice e non mi sembra che possa essere semplificato nel senso di ridurre il numero totale di righe. Potrebbe essere reso meno dettagliato se ti liberassi di alcune delle parentesi graffe inutili e fastidiose, ma suppongo che se ti è piaciuta l'idea l'avresti già fatta:

        if (arrayX == 0)
        {
            if (board.GetBoard(arrayX + 1, arrayY - 1).Piece == null)
                return true;
        }
        else if (arrayX == 7)
        {
            if (board.GetBoard(arrayX - 1, arrayY - 1).Piece == null)
                return true;
        }

Tuttavia, c'è una cosa che potresti provare a vedere se semplificherebbe il tuo codice: definisci un struct immutabile per contenere un punto.

struct Point
{
    readonly int x; //these are 32-bit, so the entire struct will fit inside a
    readonly int y; //   machine word in a 64-bit architecture.
    Point( int x, int y )
    { 
        Assert( x >= 0 && x < 7 );  
        Assert( y >= 0 && y < 7 ); 
        this.x = x;  
        this.y = y; 
    }
    Point left { get { Assert( x >= 0 );  return new Point( x - 1, y ); } }
    Point right { get { Assert( x <= 7 );  return new Point( x + 1, y ); } }
    bool isLeftmost { get { return x == 0; } }
    bool isRightmost { get { return x == 7; } }
    ...
}

quindi, sarai in grado di aggiungere cose interessanti alla tua struttura, come questa:

    IEnumerable<Point> EnumerateSurrounding()
    {
        for( int dx = -1;  dx <= 1;  dx++ )
        {
            for( int dy = -1;  dy <= 1;  dy++ )
            {
                int xx = x + dx; 
                int yy = y + dy;
                if( xx < 0 || xx > 7 )
                     continue;
                if( yy < 0 || yy > 7 )
                     continue;
                if( xx == 0 && yy == 0 )
                     continue;
                yield return new Point( xx, xy );
            }
        }
    }

Quindi, potrai visitare tutte le celle che circondano una determinata cella in questo modo:

foreach( Point p in mypoint.EnumerateSurrounding() )
{
    //do something with p here
}

Dichiarazione di non responsabilità: ho appena digitato tutto il codice sopra, quindi è destinato ad avere errori di sintassi e forse anche errori logici. Non fidarti ciecamente, leggi attentamente e usa il tuo giudizio.

    
risposta data 10.02.2015 - 00:23
fonte
0

Sembra che tu stia verificando casi limite. Spesso è possibile ridurre il margine del test del caso rimuovendo i bordi dal problema. Invece della scacchiera 8x8, fai internamente la tavola 12x12. (Si noti che ciò sarebbe più semplice in un linguaggio come Pascal che consente limiti di array non standard.) Ora non ci si deve preoccupare della maggior parte dei test sui bordi: c'è abbastanza spazio là fuori che esiste la destinazione di qualsiasi mossa possibile. Devi ancora respingere le mosse che vadano fuori dal bordo, ma anche questo può essere fatto con una singola affermazione (avere una serie di quadrati buoni e cattivi, se la cella del prospetto è una cella cattiva che rifiuta la mossa.)

    
risposta data 10.02.2015 - 06:00
fonte

Leggi altre domande sui tag