Changing the way the SEO moves

Changing the domain name does not have to be the cause for any (long lasting) negative SEO effects. As long as you plan the move carefully and do it correctly, you do not have to fear ranking losses. In order to move your domain, you should tell Google that you changed the address of your website. You do so through the Google Search Console (GSC) and then you have to redirect all the content from the old domain to the new, with the help of 301-redirects.

The following steps and requirements are necessary in order to ensure the domain move goes through without a hitch:

the domain you used so far has to be verified in the GSC
the new domain also has to be verified in the GSC (using the same account)
you have to tell Google about the change of address for the domain, using the GSC
all content on the old domain has to be redirected to the new domain name, using 301-redirects
you need to check the internal links
get Google to crawl the new domain

security – Considering the potential upcoming legislation in the U.S., what moves can someone make before it goes into effect to protect themselves?

The infrastructure bill includes some crypto provisions. There are varying opinions on just how bad these provisions are, but regardless of severity they do attempt to cut at cryptocurrency in general.

Now, as we know, Bitcoin is not actually anonymous, despite much of the misinformation that spread years ago. Especially when using an exchange where they verify your identity to buy/sell.

What are some ways to protect yourself and your money/investment when it comes to potential government interference in crypto markets?
What about things miners can do to protect themselves as well?

architecture – Record/History of moves and state of entire game after that move for a Turn based game

My first question here! 🙂

Im trying to conceptualize how I would go about recording the moves of my players, and also the state of my game after the calculations of that move.

For example, Final Fantasy tactics.

  1. UnitA makes an attack
  2. Calculations will be done
  3. Store the last move, and also the state of the game after that move.

In the example above, for example, I use Firebase firestore to update the players of the state of the game. In that firestore document, i will update it with the latest move and its effects, together with the latest state of game.

My concern is in number 3, where should I put the record of the previous moves and state of the game after those moves. The purpose of this is for example, I want to replay the match. With records of each moves and states of the game after those moves, I will be able to replay the match accurately. My concern is, it seems recording all these seems huge data because, if a unit moves, I would have to store the entire state of the game, which includes all units hp/position in tile map/buffs/ abilities states(cooldown) etc.

What I have thought of so far
Option:
A: (Bad)Store them in same document as the latest document snapshot. Like create an array where it will contain the record of move and snapshot for that move
B: (I think better than A but so many documents will be created) Create one firestore document for each move with the state of the game after that move and store them on a separate firestore collection.

May I ask for advice.

Thanks in advance

c++ – Chess engine generates moves

I am currently writing a chess engine to improve my C++. I was able to improve my first results in terms of performance. (It is still really weak, but it does not lose a queen in one move)

I ended up having massive problems regarding namespaces in move generation.

It is really not great.

Here is some code:

#pragma once
#include <list>
#include <memory>
#include <string>
#include <vector>
#include <thread>
#include <functional>
#include "Board.h"
#include "Node.h"
#include "Utility.h"

namespace OdinConstants {
    static const std::string standardBoardFen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
    static const double cpuct = 2.0f;
}

class Node;

class Odin {
public:
    Odin();

    long positions_calculated_{0};
    std::shared_ptr<Node> start_node_;

    inline void searchOn() {
        searching_ = true;
        setUpForCalculations();
    }


    inline void searchOff() {
        searching_ = false;
    }

    void search();
    void setPosition(const std::string& fen, const std::vector<std::string>& moves);
    inline void setPosition(const Board& board) { 
        start_node_ =
          std::make_shared<Node>(board,std::nullopt, std::nullopt, nullptr);
      positions_calculated_ = 0;
    }
    static double evaluatePosition(const Board &board);

    std::tuple<int, int, Figure> bestMove() const;


private:
    std::thread computingThread_{};
    bool searching_{false};
    bool in_chess_{true};

    void setUpForCalculations();
    void computeNext();


};

 /* //////////////////////////////////////////////////
 * Move Generation
 *///////////////////////////////////////////////////

Board makeMove(const Board &b, std::tuple<int, int, Figure>);
/*
 * Checks if king could be "captured" in the next move and would therefore be in
 * check.
 */
bool isCheck(const Board &board, Color to_be_checked);

//all moves disregardingCheck
void generateAllMoves(std::vector<std::tuple<int, int, Figure>>& moves, const Board& board);
//Checks if any move, can reach this field
bool hasMoveToField(std::vector<std::tuple<int, int, Figure>>& moves, const Board& board, int to_field);
//all moves regarding check
void generateAllLegalMoves(std::vector<std::tuple<int, int, Figure>> &moves, const Board& board);
/*
 * filters all Moves which would be illegal, because color would check itself or
 * not escape a check
 */
void extractLegalMoves(std::vector<std::tuple<int, int, Figure>>& moves, const Board & board,
                       std::function<void(std::vector<std::tuple<int, int, Figure>>&, const Board &)> generator);

namespace PAWNMOVES {
void generateAllPawnMovesWithWhite(std::vector<std::tuple<int, int, Figure>> &pawn_moves, const Board &board, int field_num);
void generateAllPawnMovesWithBlack(std::vector<std::tuple<int, int, Figure>> &pawn_moves, const Board &board, int field_num);
void generateAllPawnMoves(std::vector<std::tuple<int, int, Figure>>& , const Board& board);
}
namespace KNIGHTMOVES {
void addIfMoveable(std::vector<std::tuple<int, int, Figure>>& moves, const int fromi, const int fromj, const int toi, const int toj, const Board& b);
void generateAllKnightMoves(std::vector<std::tuple<int, int, Figure>> &, const Board &board);
}
namespace LONGRANGEPIECEMOVES {
template <int dX, int dY> void generateMoves(std::vector<std::tuple<int, int, Figure>>& moves, const Board& board, const int y, const int x);
void generateAllBishopMoves(std::vector<std::tuple<int, int, Figure>>& , const Board& board);
void generateAllRookMoves(std::vector<std::tuple<int, int, Figure>>& , const Board& board);
void generateAllQueenMoves(std::vector<std::tuple<int, int, Figure>>&, const Board& board);
}

namespace KINGMOVES {
/*
* Generates a king step in any direction. Where dX, dY is the directrion.
 * For some weird reason, I do not fully understand: generateOneSteps needs to be header defined.
*/
template<int dX, int dY>
void generateOneSteps(const int j, const int i,
                                 std::vector<std::tuple<int, int, Figure>> &moves,
                                 const Board &board) {

  int toi = i + dY;
  int toj = j + dX;
  if (!inBounds(toi, toj)) {
    return;
  }
  if (board(toi)(toj) == EMPTY.value()) {
    moves.push_back(std::make_tuple((8 * i + j), (8 * toi + toj), EMPTY));
  } else if (board(toi)(toj) * (static_cast<int>(board.to_move_)) <=
      EMPTY.value()) {
    moves.push_back(std::make_tuple((8 * i + j), (8 * toi + toj), EMPTY));
  }
}
void generateAllCastling(int i, int j, std::vector<std::tuple<int, int, Figure>> &moves, const Board &board);
void generateAllKingMoves(std::vector<std::tuple<int, int, Figure>>&, const Board& board);
}

inline bool hasNoFigure(const Board& board, const int rank, const int line) {
  if (!inBounds(rank, line)) {
    return false;
  }  
  return board(rank)(line) == 0;
}

inline bool hasBlackFigure(const Board& board, const int rank, const int line) {
  if (!inBounds(rank, line)) {
    return false;
  }
  return board(rank)(line) < 0;
}

inline bool hasWhiteFigure(const Board& board, const int rank, const int line) {
  if (!inBounds(rank, line)) {
     return false;
  }
  return board(rank)(line) > 0;
}

/*
 * This method checks if the given move, does not make the king takeable, ensures the King is still protected.
 */
bool checkIfMoveIsIllegalDueCheck(const Board &b, std::tuple<int, int, Figure> move);

/*
 * This currys checkIfMoveIsIllegalDueCheck(const Board &b, std::tuple<int, int, Figure> move);
 */
inline std::function<bool(std::tuple<int, int, Figure>)> checkIfMoveIsIllegalDueCheck(const Board& b){
  return (b)(std::tuple<int, int, Figure> move) -> bool {
    return checkIfMoveIsIllegalDueCheck(b, move);
  };
}

bool isCheckMate(const Board& b);
bool isStaleMate(const Board& b);

And here are additional files.

// Pawnlogic.cc
// Created by Niclas Schwalbe on 30.05.21.
//
#include "Odin.h"

inline void generatePawnPromotion(std::vector<std::tuple<int, int, Figure>> &seq,
                                  const int field,
                                  const int new_field) {
  seq.push_back(std::make_tuple(field, new_field, BKNIGHT));
  seq.push_back(std::make_tuple(field, new_field, BBISHOP));
  seq.push_back(std::make_tuple(field, new_field, BROOK));
  seq.push_back(std::make_tuple(field, new_field, BQUEEN));
}

void PAWNMOVES::generateAllPawnMovesWithWhite(std::vector<std::tuple<int, int, Figure>> &pawn_moves,
                                   const Board &board,
                                   int field_num) {
  int rank = field_num / 8;
  int line = field_num % 8;

  if (hasNoFigure(board, rank + 1, line)) {
    int new_field{field_num + 8};
    if (rank == 6) {
      generatePawnPromotion(pawn_moves, field_num, new_field);
    } else {
      pawn_moves.push_back(std::make_tuple(field_num, new_field, EMPTY));
    }
  }

  if (rank == 1 && hasNoFigure(board, rank + 2, line) && hasNoFigure(board, rank + 1, line)) {
    pawn_moves.push_back(std::make_tuple(field_num, field_num + 16, EMPTY));
  }

  int left = line - 1;
  int right = line + 1;

  if (0 <= left && left < 8 && hasBlackFigure(board, rank + 1, left)) {
    int new_field{field_num + 7};
    if (rank == 6) {
      generatePawnPromotion(pawn_moves, field_num, new_field);
    } else {
      pawn_moves.push_back(std::make_tuple(field_num, new_field, EMPTY));
    }
  }
  if (0 <= right && right < 8 && hasBlackFigure(board, rank + 1, right)) {
    int new_field{field_num + 9};
    if (rank == 6) {
      generatePawnPromotion(pawn_moves, field_num, new_field);
    } else {
      pawn_moves.push_back(std::make_tuple(field_num, new_field, EMPTY));
    }
  }
}

void PAWNMOVES::generateAllPawnMovesWithBlack(std::vector<std::tuple<int, int, Figure>> &pawn_moves,
                                   const Board &board,
                                   int field_num) {
  int rank = field_num / 8;
  int line = field_num % 8;

  if (hasNoFigure(board, rank - 1, line)) {
    int new_field{field_num - 8};
    if (rank == 1) {
      generatePawnPromotion(pawn_moves, field_num, new_field);
    } else {
      pawn_moves.push_back(std::make_tuple(field_num, new_field, EMPTY));
    }
  }

  if (rank == 6 && hasNoFigure(board, rank - 2, line) && hasNoFigure(board, rank - 1, line)) {
    pawn_moves.push_back(std::make_tuple(field_num, field_num - 16, EMPTY));
  }

  int left = line - 1;
  int right = line + 1;

  if (0 <= left && left < 8 && hasWhiteFigure(board, rank - 1, left)) {
    int new_field{field_num - 9};
    if (rank == 1) {
      generatePawnPromotion(pawn_moves, field_num, new_field);
    } else {
      pawn_moves.push_back(std::make_tuple(field_num, new_field, EMPTY));
    }
  }
  if (0 <= right && right < 8 && hasWhiteFigure(board, rank - 1, right)) {
    int new_field{field_num - 7};
    if (rank == 1) {
      generatePawnPromotion(pawn_moves, field_num, new_field);
    } else {
      pawn_moves.push_back(std::make_tuple(field_num, new_field, EMPTY));
    }
  }

}


void PAWNMOVES::generateAllPawnMoves(std::vector<std::tuple<int, int, Figure>> &moves, const Board &board) {

  auto pawn = board.to_move_ == Color::WHITE ? WPAWN : BPAWN;

  for(int fieldnum = 0; fieldnum < 64; fieldnum++){
    if(board(fieldnum) == pawn.value()){
      switch (board.to_move_) {
        case Color::BLACK: generateAllPawnMovesWithBlack(moves, board, fieldnum);
          break;
        case Color::WHITE: generateAllPawnMovesWithWhite(moves, board, fieldnum);
          break;
      }
    }
  }

}



Movegeneration.cc


//
// Created by Niclas Schwalbe on 13.07.21.
//

#include "Odin.h"

Board makeMove(const Board &old_b, std::tuple<int, int, Figure> t) {
  // copy Board
  Board new_b{old_b};
  const auto from_field{std::get<0>(t)};
  const auto to_field{std::get<1>(t)};
  const auto promotion{std::get<2>(t)};

  // value of the piece to be moved.
  int temp = new_b(from_field);
  new_b(from_field) = EMPTY.value();

  // is the move an en passant?
  auto pawn = old_b.to_move_ == Color::WHITE ? WPAWN : BPAWN;
  if (old_b(from_field) == pawn.value() &&
      old_b.en_passant_field_ == to_field) {
    if (old_b.to_move_ == Color::WHITE) {
      new_b(to_field - 8) = EMPTY.value();
    } else {
      new_b(to_field + 8) = EMPTY.value();
    }
  }

  // is it pawn move with 2 steps, if yes set en_passant
  if (old_b(from_field) == pawn.value() && abs(from_field - to_field) == 16) {
    new_b.en_passant_field_ =
        new_b.to_move_ == Color::WHITE ? from_field + 8 : from_field - 8;
  } else {
    new_b.en_passant_field_ = -1;
  }

  // if move is castle, then set rook and remove castling rights
  auto king = old_b.to_move_ == Color::WHITE ? WKING : BKING;
  if (old_b(from_field) == king.value() && abs(from_field - to_field) == 2) {
    if (to_field % 8 < 5) {
      new_b((from_field / 8) * 8) = EMPTY.value();
      new_b((from_field / 8) * 8 + 3) = king.color() * WROOK.value();
    } else {
      new_b((from_field / 8) * 8 + 7) = EMPTY.value();
      new_b((from_field / 8) * 8 + 5) = king.color() * WROOK.value();
    }
    if (old_b.to_move_ == Color::WHITE) {
      new_b.long_castle_white_ = false;
      new_b.short_castle_white_ = false;
    } else {
      new_b.long_castle_black_ = false;
      new_b.short_castle_black_ = false;
    }
  }

  // Set new position, promote pawn if necessary
  if (promotion.value() == 0) {
    new_b(to_field) = temp;
  } else {
    new_b(to_field) = promotion.value();
  }

  // change color
  new_b.to_move_ = old_b.to_move_ == Color::WHITE ? Color::BLACK : Color::WHITE;

  return new_b;
}

void generateAllLegalMoves(std::vector<std::tuple<int, int, Figure>> &moves,
                           const Board &board) {
  extractLegalMoves(moves, board, generateAllMoves);
}

void generateAllMoves(std::vector<std::tuple<int, int, Figure>> &moves,
                      const Board &board) {
  bool colb = Color::WHITE == board.to_move_;
  auto pawn = colb ? WPAWN : BPAWN;
  auto knight = colb ? WKNIGHT : BKNIGHT;
  auto bishop = colb ? WBISHOP : BBISHOP;
  auto rook = colb ? WROOK : BROOK;
  auto queen = colb ? WQUEEN : BQUEEN;
  auto king = colb ? WKING : BKING;

  for (int fieldnum = 0; fieldnum < 64; fieldnum++) {
    auto val = board(fieldnum);
    int y = fieldnum / 8;
    int x = fieldnum % 8;

    if (val == pawn.value()) {

      switch (board.to_move_) {
        case Color::WHITE: PAWNMOVES::generateAllPawnMovesWithWhite(moves, board, fieldnum);
                           break;
        case Color::BLACK: PAWNMOVES::generateAllPawnMovesWithBlack(moves, board, fieldnum);
      }

    } else if (val == knight.value()) {

      KNIGHTMOVES::addIfMoveable(moves, y, x, y - 2, x + 1, board);
      KNIGHTMOVES::addIfMoveable(moves, y, x, y - 2, x - 1, board);
      KNIGHTMOVES::addIfMoveable(moves, y, x, y + 2, x + 1, board);
      KNIGHTMOVES::addIfMoveable(moves, y, x, y + 2, x - 1, board);
      KNIGHTMOVES::addIfMoveable(moves, y, x, y - 1, x + 2, board);
      KNIGHTMOVES::addIfMoveable(moves, y, x, y - 1, x - 2, board);
      KNIGHTMOVES::addIfMoveable(moves, y, x, y + 1, x + 2, board);
      KNIGHTMOVES::addIfMoveable(moves, y, x, y + 1, x - 2, board);

    } else if (val == bishop.value()) {

      LONGRANGEPIECEMOVES::generateMoves<1, 1>(moves, board, y, x);
      LONGRANGEPIECEMOVES::generateMoves<1, -1>(moves, board, y, x);
      LONGRANGEPIECEMOVES::generateMoves<-1, -1>(moves, board, y, x);
      LONGRANGEPIECEMOVES::generateMoves<-1, 1>(moves, board, y, x);

    } else if (val == rook.value()) {

      LONGRANGEPIECEMOVES::generateMoves<1, 0>(moves, board, y, x);
      LONGRANGEPIECEMOVES::generateMoves<0, -1>(moves, board, y, x);
      LONGRANGEPIECEMOVES::generateMoves<-1, 0>(moves, board, y, x);
      LONGRANGEPIECEMOVES::generateMoves<0, 1>(moves, board, y, x);

    } else if (val == queen.value()) {

      LONGRANGEPIECEMOVES::generateMoves<1, 1>(moves, board, y, x);
      LONGRANGEPIECEMOVES::generateMoves<1, 0>(moves, board, y, x);
      LONGRANGEPIECEMOVES::generateMoves<1, -1>(moves, board, y, x);
      LONGRANGEPIECEMOVES::generateMoves<-1, -1>(moves, board, y, x);
      LONGRANGEPIECEMOVES::generateMoves<-1, 0>(moves, board, y, x);
      LONGRANGEPIECEMOVES::generateMoves<-1, 1>(moves, board, y, x);
      LONGRANGEPIECEMOVES::generateMoves<0, -1>(moves, board, y, x);
      LONGRANGEPIECEMOVES::generateMoves<0, 1>(moves, board, y, x);

    } else if (val == king.value()) {


      KINGMOVES::generateOneSteps<1, 0>(x, y, moves, board);
      KINGMOVES::generateOneSteps<1, 1>(x, y, moves, board);
      KINGMOVES::generateOneSteps<1, -1>(x, y, moves, board);
      KINGMOVES::generateOneSteps<-1, 0>(x, y, moves, board);
      KINGMOVES::generateOneSteps<-1, -1>(x, y, moves, board);
      KINGMOVES::generateOneSteps<-1, 1>(x, y, moves, board);
      KINGMOVES::generateOneSteps<0, -1>(x, y, moves, board);
      KINGMOVES::generateOneSteps<0, 1>(x, y, moves, board);
      KINGMOVES::generateAllCastling(x, y, moves, board);

    }
  }
}

void extractLegalMoves(
    std::vector<std::tuple<int, int, Figure>> &moves, const Board &board,
    std::function<void(std::vector<std::tuple<int, int, Figure>> &,
                       const Board &)>
    generator) {
  std::vector<std::tuple<int, int, Figure>> new_moves;
  generator(new_moves, board);

  for (auto &t : new_moves) {
    if (!checkIfMoveIsIllegalDueCheck(board, t)) {
      moves.push_back(t);
    }
  }
}

bool checkIfMoveIsIllegalDueCheck(const Board &b,
                                  std::tuple<int, int, Figure> move) {
  Board new_board = makeMove(b, move);
  return isCheck(new_board, b.to_move_);
}



bool hasMoveToField(const Board &old_b, int to_field) {
  auto color = old_b.to_move_ == Color::WHITE ? 1 : -1;
  int x = to_field % 8;
  int y = to_field / 8;
  Figure pawn{WPAWN.value(), color};
  Figure knight{WKNIGHT.value(), color};
  Figure bishop{WBISHOP.value(), color};
  Figure rook{WROOK.value(), color};
  Figure queen{WQUEEN.value(), color};
  Figure king{WKING.value(), color};
  Board board{old_b};
  board.to_move_ = (board.to_move_ == Color::WHITE) ? Color::BLACK : Color::WHITE;

  std::vector<std::tuple<int, int, Figure>> knightmoves;
  KNIGHTMOVES::addIfMoveable(knightmoves, y, x, y - 2, x + 1, board);
  KNIGHTMOVES::addIfMoveable(knightmoves, y, x, y - 2, x - 1, board);
  KNIGHTMOVES::addIfMoveable(knightmoves, y, x, y + 2, x + 1, board);
  KNIGHTMOVES::addIfMoveable(knightmoves, y, x, y + 2, x - 1, board);
  KNIGHTMOVES::addIfMoveable(knightmoves, y, x, y - 1, x + 2, board);
  KNIGHTMOVES::addIfMoveable(knightmoves, y, x, y - 1, x - 2, board);
  KNIGHTMOVES::addIfMoveable(knightmoves, y, x, y + 1, x + 2, board);
  KNIGHTMOVES::addIfMoveable(knightmoves, y, x, y + 1, x - 2, board);

  for(auto& (from, to, E) : knightmoves){
    if(board(to) == knight.value()){
      return true;
    }
  }

  std::vector<std::tuple<int, int, Figure>> bishopmoves;
  LONGRANGEPIECEMOVES::generateMoves<1, 1>(bishopmoves, board, y, x);
  LONGRANGEPIECEMOVES::generateMoves<1, -1>(bishopmoves, board, y, x);
  LONGRANGEPIECEMOVES::generateMoves<-1, -1>(bishopmoves, board, y, x);
  LONGRANGEPIECEMOVES::generateMoves<-1, 1>(bishopmoves, board, y, x);

  for(auto& (from, to, E) : bishopmoves){
    if(board(to) == bishop.value() || board(to) == queen.value()){
      return true;
    }
  }

  std::vector<std::tuple<int, int, Figure>> rookmoves;
  LONGRANGEPIECEMOVES::generateMoves<1, 0>(rookmoves, board, y, x);
  LONGRANGEPIECEMOVES::generateMoves<0, -1>(rookmoves, board, y, x);
  LONGRANGEPIECEMOVES::generateMoves<-1, 0>(rookmoves, board, y, x);
  LONGRANGEPIECEMOVES::generateMoves<0, 1>(rookmoves, board, y, x);

  for(auto& (from, to, E) : rookmoves){
    if(board(to) == rook.value() || board(to) == queen.value()){
      return true;
    }
  }

  std::vector<std::tuple<int, int, Figure>> kingmoves;
  KINGMOVES::generateOneSteps<1, 0>(x, y, kingmoves, board);
  KINGMOVES::generateOneSteps<1, 1>(x, y, kingmoves, board);
  KINGMOVES::generateOneSteps<1, -1>(x, y, kingmoves, board);
  KINGMOVES::generateOneSteps<-1, 0>(x, y, kingmoves, board);
  KINGMOVES::generateOneSteps<-1, -1>(x, y, kingmoves, board);
  KINGMOVES::generateOneSteps<-1, 1>(x, y, kingmoves, board);
  KINGMOVES::generateOneSteps<0, -1>(x, y, kingmoves, board);
  KINGMOVES::generateOneSteps<0, 1>(x, y, kingmoves, board);

  for(auto& (from, to, E) : kingmoves){
    if(board(to) == king.value()){
      return true;
    }
  }

  switch (old_b.to_move_) {
    case Color::WHITE: return (inBounds(x-1,y-1) && board(y-1)(x-1) == pawn.value()) || (inBounds(x+1,y-1) && board(y-1)(x+1) == pawn.value());
    case Color::BLACK: return (inBounds(x-1,y+1) && board(y+1)(x-1) == pawn.value()) || (inBounds(x+1,y+1) && board(y+1)(x+1) == pawn.value());
  }


}

bool isCheck(const Board &b, Color color_to_be_checked) {
  std::vector<std::tuple<int, int, Figure>> moves;
  if (b.to_move_ == color_to_be_checked) {
    Board passTurn{b};
    passTurn.to_move_ =
        b.to_move_ == Color::WHITE ? Color::BLACK : Color::WHITE;
    return isCheck(passTurn, color_to_be_checked);
  } else {

    int field_num{0};

    auto figure = b.to_move_ == Color::WHITE ? BKING : WKING;

    for (auto p : b) {
      if (p == figure.value()) {
        break;
      }
      field_num++;
    }

    return hasMoveToField(b, field_num);
  }
}

bool isCheckMate(const Board &board) {
  if (!isCheck(board, board.to_move_)) {
    return false;
  }

  //smarter way
  if (board.is_end_position.has_value()) {
    return board.is_end_position.value();
  }  
  //else Bruteforce
  std::vector<std::tuple<int, int, Figure>> vec{};
  generateAllLegalMoves(vec, board);
  return vec.size() == 0;
}

bool isStaleMate(const Board &board) {
  if (isCheck(board, board.to_move_)) {
    return false;
  }
  //smarter way
  if (board.is_end_position.has_value()) {
    return board.is_end_position.value();
  }  
  //else Brutforce
  std::vector<std::tuple<int, int, Figure>> vec{};
  generateAllLegalMoves(vec, board);
  return vec.size() == 0;
}

Longrangepiecelogic.cc

#include "Odin.h"

/*
* Generates long range piece moves. Where dX, dY is the direction the piece is going to.
* A rook and a rook need 4 directions
* A queen needs 6 directions
*/
template <int dX, int dY>
void LONGRANGEPIECEMOVES::generateMoves(std::vector<std::tuple<int, int, Figure>>& moves,
                   const Board& board, const int y, const int x) {
  int tox = x;
  int toy = y;
  for (int i = 0; i < 8 && inBounds(tox + dX, toy + dY); i++) {
    tox += dX;
    toy += dY;
    if (board(toy)(tox) == EMPTY.value()) {
      moves.push_back(std::make_tuple((8 * y + x), (8 * toy + tox), EMPTY));
      continue;
    } else if (board(toy)(tox) * (static_cast<int>(board.to_move_)) <=
        EMPTY.value()) {
      moves.push_back(std::make_tuple((8 * y + x), (8 * toy + tox), EMPTY));
      break;
    }
    break;
  }
}



void LONGRANGEPIECEMOVES::generateAllBishopMoves(std::vector<std::tuple<int, int, Figure>>& moves,
                            const Board& board) {
  auto piece = board.to_move_ == Color::WHITE ? WBISHOP : BBISHOP;
  for (int y = 0; y < 8; y++) {
    for (int x = 0; x < 8; x++) {
      if (board(y)(x) == piece.value()) {
        LONGRANGEPIECEMOVES::generateMoves<1, 1>(moves, board, y, x);
        LONGRANGEPIECEMOVES::generateMoves<1, -1>(moves, board, y, x);
        LONGRANGEPIECEMOVES::generateMoves<-1, -1>(moves, board, y, x);
        LONGRANGEPIECEMOVES::generateMoves<-1, 1>(moves, board, y, x);
      }
    }
  }
}

void LONGRANGEPIECEMOVES::generateAllRookMoves(std::vector<std::tuple<int, int, Figure>>& moves,
                          const Board& board) {
  auto piece = board.to_move_ == Color::WHITE ? WROOK : BROOK;
  for (int y = 0; y < 8; y++) {
    for (int x = 0; x < 8; x++) {
      if (board(y)(x) == piece.value()) {
        LONGRANGEPIECEMOVES::generateMoves<1, 0>(moves, board, y, x);
        LONGRANGEPIECEMOVES::generateMoves<0, -1>(moves, board, y, x);
        LONGRANGEPIECEMOVES::generateMoves<-1, 0>(moves, board, y, x);
        LONGRANGEPIECEMOVES::generateMoves<0, 1>(moves, board, y, x);
      }
    }
  }
}

void LONGRANGEPIECEMOVES::generateAllQueenMoves(std::vector<std::tuple<int, int, Figure>>& moves,
                          const Board& board) {
  auto piece = board.to_move_ == Color::WHITE ? WQUEEN : BQUEEN;
  for (int y = 0; y < 8; y++) {
    for (int x = 0; x < 8; x++) {
      if (board(y)(x) == piece.value()) {
        LONGRANGEPIECEMOVES::generateMoves<1, 1>(moves, board, y, x);
        LONGRANGEPIECEMOVES::generateMoves<1, -1>(moves, board, y, x);
        LONGRANGEPIECEMOVES::generateMoves<-1, -1>(moves, board, y, x);
        LONGRANGEPIECEMOVES::generateMoves<-1, 1>(moves, board, y, x);
        LONGRANGEPIECEMOVES::generateMoves<1, 0>(moves, board, y, x);
        LONGRANGEPIECEMOVES::generateMoves<0, -1>(moves, board, y, x);
        LONGRANGEPIECEMOVES::generateMoves<-1, 0>(moves, board, y, x);
        LONGRANGEPIECEMOVES::generateMoves<0, 1>(moves, board, y, x);
      }
    }
  }
}

Kinglogic.cc

#include "Odin.h"


/*
* Generates all castling moves. If the king is in check after the castling, the move will be generated and can be filtered out later.
* However, if the king would be in check while crossing, the move would not be added.
*/
void KINGMOVES::generateAllCastling(int j, int i,
                         std::vector<std::tuple<int, int, Figure>> &moves,
                         const Board &board) {
  //check if King is at original position.
  if (!((board.to_move_ == Color::BLACK && i == 7 && j == 4) || (board.to_move_ == Color::WHITE && i == 0 && j == 4))) {
    return;
  }

  switch (board.to_move_) {
    /*
    * If the side still has castling sides, the space between king and rook is free, the rook still is at original position
    * and the king could not be captured while moving to its desired position.
    */


    //case WHITE
    case Color::WHITE:
      if (board.long_castle_white_ &&
          !checkIfMoveIsIllegalDueCheck(board, std::make_tuple(4, 3, EMPTY)) &&
          board(0)(1) == EMPTY.value() &&
          board(0)(2) == EMPTY.value() &&
          board(0)(3) == EMPTY.value() &&
          board(0)(0) == WROOK.value()) {
        moves.push_back(std::make_tuple(4, 2, EMPTY));
      }
      if (board.short_castle_white_ &&
          !checkIfMoveIsIllegalDueCheck(board, std::make_tuple(4, 5, EMPTY)) &&
          board(0)(5) == EMPTY.value() &&
          board(0)(6) == EMPTY.value() &&
          board(0)(7) == WROOK.value()) {
        moves.push_back(std::make_tuple(4, 6, EMPTY));
      }
      break;
      //case BLACK
    default:
      if (board.long_castle_black_ &&
          !checkIfMoveIsIllegalDueCheck(board, std::make_tuple(60, 59, EMPTY)) &&
          board(7)(1) == EMPTY.value() &&
          board(7)(2) == EMPTY.value() &&
          board(7)(3) == EMPTY.value() &&
          board(7)(0) == BROOK.value()) {
        moves.push_back(std::make_tuple(60, 58, EMPTY));
      }
      if (board.short_castle_black_ &&
          !checkIfMoveIsIllegalDueCheck(board, std::make_tuple(60, 61, EMPTY)) &&
          board(7)(5) == EMPTY.value() &&
          board(7)(6) == EMPTY.value() &&
          board(7)(7) == BROOK.value()) {
        moves.push_back(std::make_tuple(60, 62, EMPTY));
      }
  }
}


void KINGMOVES::generateAllKingMoves(std::vector<std::tuple<int, int, Figure>> &moves,
                          const Board &board) {
  auto piece = board.to_move_ == Color::WHITE ? WKING : BKING;
  for (int i = 0; i < 8; i++) {
    for (int j = 0; j < 8; j++) {
      if (board(i)(j) == piece.value()) {
        KINGMOVES::generateOneSteps<1, 0>(j, i, moves, board);
        KINGMOVES::generateOneSteps<1, 1>(j, i, moves, board);
        KINGMOVES::generateOneSteps<1, -1>(j, i, moves, board);
        KINGMOVES::generateOneSteps<-1, 0>(j, i, moves, board);
        KINGMOVES::generateOneSteps<-1, -1>(j, i, moves, board);
        KINGMOVES::generateOneSteps<-1, 1>(j, i, moves, board);
        KINGMOVES::generateOneSteps<0, -1>(j, i, moves, board);
        KINGMOVES::generateOneSteps<0, 1>(j, i, moves, board);
        KINGMOVES::generateAllCastling(j, i, moves, board);
        return;
      }
    }
  }
}

Knightlogic.cc

#include <vector>
#include <tuple>
#include "Odin.h"

//adds Knight move if moveable
inline void KNIGHTMOVES::addIfMoveable(std::vector<std::tuple<int, int, Figure>>& moves, const int fromi,
                          const int fromj, const int toi, const int toj, const Board& b) {

  int opposite = b.to_move_ == Color::WHITE ? -1 : 1;
  if (!inBounds(toi, toj)) {
    return;
  }
  if (opposite * b(toi)(toj) >= 0) {
    int old_field = fromi * 8 + fromj;
    int new_field = toi * 8 + toj;
    moves.push_back(std::make_tuple(old_field, new_field, EMPTY));
  }
  return;
}


void KNIGHTMOVES::generateAllKnightMoves(std::vector<std::tuple<int, int, Figure>>& moves,
                            const Board& board) {
  auto piece = board.to_move_ == Color::WHITE ? WKNIGHT : BKNIGHT;
  for (int i = 0; i < 8; i++) {
    for (int j = 0; j < 8; j++) {
      if (board(i)(j) == piece.value()) {
        KNIGHTMOVES::addIfMoveable(moves, i, j, i - 2, j + 1, board);
        KNIGHTMOVES::addIfMoveable(moves, i, j, i - 2, j - 1, board);
        KNIGHTMOVES::addIfMoveable(moves, i, j, i + 2, j + 1, board);
        KNIGHTMOVES::addIfMoveable(moves, i, j, i + 2, j - 1, board);
        KNIGHTMOVES::addIfMoveable(moves, i, j, i - 1, j + 2, board);
        KNIGHTMOVES::addIfMoveable(moves, i, j, i - 1, j - 2, board);
        KNIGHTMOVES::addIfMoveable(moves, i, j, i + 1, j + 2, board);
        KNIGHTMOVES::addIfMoveable(moves, i, j, i + 1, j - 2, board);
      }  

    }
  }
}

I have some general questions:

  1. As you see in the Odin.h file, namespaces are declared. However, for some weird reasons, I had to include the KINGMOVES::generateOneStep into the header file and could not define it in the kinglogic.cc, while this was possible with the similar generatesMoves from the longrangepiecelogic.cc. How to fix that?

  2. How could a better structure of this move generation look like?

  3. There are some functions, where White and Black do different things (Pawnlogic.cc) This make it really clumsy. Any idea on how to fix that?

  4. What else would you improve?

My KODAK Film camera (M35) is not advancing my film correctly. I turn the film advance wheel and it moves but it doesnt stop to allow the shutter?

This is a kodak film camera. Im not sure how to make the shutter work again.

unreal 4 – Solved UE4, How do it to where when my camera looks up and down my character mesh which is a hand also moves up and down

Looking Straight

Looking Up

I am using the blueprint system on the ThirdPersonTemplate, please someone help me i have been stuck here for quite some time…

— SOLVED
For anyone wondering all you have to do is set the character to use the controller rotation pitch. i did some blueprints in my animations of rotations and stuff but im not even sure if it works or if its just the pitch rotation.

UE4, How do it to where when my camera looks up and down my character mesh which is a hand also moves up and down

Looking Straight

Looking Up

I am using the blueprint system on the ThirdPersonTemplate, please someone help me i have been stuck here for quite some time

dnd 5e – Does the caster of the Incendiary Cloud spell choose the direction it moves only when it’s cast, or choose it every turn?

Every turn.

Unless I’m misunderstanding your question, the answer is in the phrase you quoted.

As you’ve quoted, the description of incendiary cloud says (emphasis mine):

(…) a direction that you choose at the start of each of your turns.

So on round 1, the caster casts incendiary cloud. It stays put for the time being.
At the start of your next turn, the caster chooses a direction.1
At the end of round 2, the cloud settles into place 10 feet away from its starting point.
At the beginning of round 3, the caster can choose again.

Each turn, the player starts by declaring a direction. Nothing says it has to be the same direction as last time.


1 I’m confused about how the cloud moves “directly away” and in a direction that is chosen, but that’s outside the scope of the question.

what is the best chart to represent how a variable moves across different categories along time?

assume the variable X can be in 4 different categories A,B,C,D in different days. how can this data be represented visually?

day1 A
day2 B
day3 C
day4 D
...

input fields – Notify error in forms. Should element moves? Best practice

When designing a form, should I design with enough space between the elements for potential errors?

So that when displaying error messages, the inputs under the error do not move because between them there was space for that messages.

Visual examples:
input movement on forms when error message

Thanks!