Chess piece hierarchy design: inheritance vs type fields

前端 未结 6 772
别跟我提以往
别跟我提以往 2021-02-15 13:23

I have a base class for pieces

 class piece;

and an array containing derived objects

piece* board[8][8];

Advantag

6条回答
  •  清酒与你
    2021-02-15 14:07

    The "super ugly switch statement" is the correct technique. It isn't ugly. It's called functional programming.

    Inheritance is completely the wrong technique. Each of the pieces moves in a different way, has a different graphic, and other properties. There's nothing common. Chess pieces are not abstract. They're a concrete collection of discrete objects.

    You have to make something common by unification: creating what is called a sum type. In Ocaml:

    type shape = Pawn | Rook | Knight | Bishop | Queen | King
    type color = Black | White
    type piece = shape * color
    type pos = { row:int;  col:int }
    
    let check_white_move piece board from to = match piece with
    | Pawn -> on_board to && (from.row = 2 && to.row = 4 or to.row = from.row + 1)
    | ....
    

    In C++ there is no proper sum type, you can use instead:

    enum shape { pawn, rook, knight, bishop, queen, king};
    ..
    bool check_white_move (..) { switch piece {
     case pawn: ...
    

    It's more clumsy. Complain to the C and C++ committees. But use the right concept. Sum types (discriminated unions, variants) are the way to unify a discrete set of concrete types. Classes and inheritance are used for representing abstractions and providing implementations thereof.

    There's nothing abstract about chess. It's all about combinations. This is not a question of advantages and disadvantages of different techniques: it's about using the correct technique.

    [BTW: yea, you can try boost variant though I can't recommend it for this application since the pieces have no associated data an enum is perfect]

提交回复
热议问题