This file is indexed.

/usr/include/osl/pieceStand.h is in libosl-dev 0.6.0-3.3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
/* pieceStand.h
 */
#ifndef OSL_PIECESTAND_H
#define OSL_PIECESTAND_H
#include "osl/move.h"
#include "osl/misc/carray.h"
#include <iosfwd>
#include <cassert>
namespace osl
{
  namespace state
  {
    class SimpleState;
  }
  /**
   * 片方の手番の持駒の枚数を記録するクラス.
   * - bit field を使うべきか迷う
   * - 一応 king を持駒にして良いことにしておく
   * レイアウト 長さ:index
   * -  reserved : 1;31
   * -  carry    : 1;
   * -  KING     : 2;28
   * -  carry    : 1;
   * -  GOLD     : 3;24
   * -  carry    : 1;
   * -  PAWN     : 5;18
   * -  carry    : 1;
   * -  LANCE    : 3;14
   * -  carry    : 1;
   * -  KNIGHT   : 3;10
   * -  carry    : 1;
   * -  SILVER   : 3; 6
   * -  carry    : 1;
   * -  BISHOP   : 2; 3
   * -  carry    : 1; 
   * -  ROOK     : 2; 0
   *
   * == を軽くするために carry off の状態を基本とする
   */
  class PieceStand
  {
  public:
    /** 持駒の表示で良く使われる順番. KINGや成駒は -1 */
    static const CArray<Ptype,7> order;
    static const unsigned int carryMask = 0x48822224;
  private:
    static const CArray<unsigned char,PTYPE_MAX+1> shift;
    static const CArray<unsigned char,PTYPE_MAX+1> mask;
    mutable unsigned int flags;
  public:
    explicit PieceStand(unsigned int value=0) : flags(value)
    {
    }
    explicit PieceStand(Player, const state::SimpleState&);
    PieceStand(int pawnCount, int lanceCount, 
	       int knightCount, int silverCount,
	       int goldCount, int bishopCount,
	       int rookCount, int kingCount) 
      : flags(0)
    {
      add(PAWN, pawnCount);
      add(LANCE, lanceCount);
      add(KNIGHT, knightCount);
      add(SILVER, silverCount);
      add(GOLD, goldCount);
      add(BISHOP, bishopCount);
      add(ROOK, rookCount);
      add(KING, kingCount);
    }

    void add(Ptype type, unsigned int num=1)
    {
      assert(isBasic(type));
      assert(num == (num & mask[type]));
      flags += (num << (shift[type]));
      assert(testCarries() == 0);	// overflow 検出
    }    
    void sub(Ptype type, unsigned int num=1)
    {
      assert(isBasic(type));
      assert(num == (num & mask[type]));
      assert(get(type) >= num);
      flags -= (num << (shift[type]));
    }

    /**
     * 加算可能なら加える.
     * 速度が必要なところでは使ってないので .cc に移動.
     */
    void tryAdd(Ptype type);
    bool canAdd(Ptype type) const;
    /**
     * 1枚以上持っていれば減らす
     */
    void trySub(Ptype type)
    {
      if (get(type))
	sub(type);
    }

    /**
     * 一種類の駒しかない
     */
    bool atMostOneKind() const;

    /**
     * pieceStand同士の加算,減算.
     * 足して良いのは,carry が立っていないpiecestandで
     * かつ,含まれる駒が高々1つ
     */
    void addAtmostOnePiece(PieceStand const& ps){
#ifndef NDEBUG
      const PieceStand copy(*this);
#endif
      assert(! ps.testCarries());
      assert(ps.atMostOneKind());
      flags += ps.getFlags();
      assert(carryUnchangedAfterAdd(copy, ps));
    }

    void subAtmostOnePiece(PieceStand const& ps){
#ifndef NDEBUG
      const PieceStand copy(*this);
#endif
      assert(! ps.testCarries());
      assert(ps.atMostOneKind());
      flags -= ps.getFlags();
      assert(carryUnchangedAfterSub(copy, ps));
    }
  private:
    bool carryUnchangedAfterAdd(const PieceStand& original, const PieceStand& other) const;
    bool carryUnchangedAfterSub(const PieceStand& original, const PieceStand& other) const;
  public:
    unsigned int get(Ptype type) const
    {
      return (flags >> (shift[type])) & mask[type];
    }
    void carriesOff() const { flags &= (~carryMask); }
    void carriesOn()  const { flags |= carryMask; }
    unsigned int testCarries() const { return (flags & carryMask); }
    bool isSuperiorOrEqualTo(PieceStand other) const
    {
      carriesOn();
      other.carriesOff();
      const bool result = (((flags - other.flags) & carryMask) == carryMask);
      carriesOff();
      return result;
    }
    /**
     * this と other が BLACK の持駒と考えた時に,
     * this の方が同じか沢山持っていれば真.
     */
    template <Player P>
    bool hasMoreThan(PieceStand other) const
    {
      if (P == BLACK)
	return isSuperiorOrEqualTo(other);
      else
	return other.isSuperiorOrEqualTo(*this);
    }
    bool hasMoreThan(Player P, PieceStand other) const
    {
      if (P == BLACK)
	return hasMoreThan<BLACK>(other);
      else
	return hasMoreThan<WHITE>(other);
    }
    unsigned int getFlags() const { return flags; }
    /** どれかの駒を一枚でも持っている */
    bool any() const { return flags; }
    /**
     * 種類毎に this と other の持駒の多い方を取る
     */
    const PieceStand max(PieceStand other) const
    {
      // other以上の数持っているptypeに対応するcarryが1になる.
      const unsigned int mask0 = ((flags|carryMask)-other.flags) & carryMask;
      // ROOK BISHOP KING用のMASKを作る
      unsigned int my_mask = mask0-((mask0&0x40000024)>>2);
      // GOLD SILVER KNIGHT LANCE用のMASKを作る
      my_mask -= (mask0&0x08022200)>>3;
      // PAWN用のMASKのみ残す
      my_mask -= (mask0&0x00800000)>>5;
      // my_mask が1のptypeの数は自分から,0のptypeはotherのところの値を
      return PieceStand((flags&my_mask)|(other.flags&~my_mask));
    }     
    /**
     * 種類毎に this と other の持駒の多い方を取る (max のalternative)
     */
    const PieceStand max2(PieceStand other) const
    {
      // other以上の数持っているptypeに対応するcarryが1になる.
      const unsigned int diff0=((flags|carryMask)-other.flags);
      const unsigned int mask0=diff0&carryMask;

      // ROOK BISHOP KING GOLD SILVER KNIGHT LANCE用のMASKを作る
      const unsigned int mask02=(mask0&0x40000024u)+(mask0&0x48022224u);
      unsigned int my_mask=mask0-(mask02>>3);

      // PAWN用のMASKのみ残す
      my_mask -= (mask0&0x00800000)>>5;
      // my_mask が1のptypeの数は自分から,0のptypeはotherのところの値を
      return PieceStand((other.flags+(diff0&my_mask))&~carryMask);
    }     

    const PieceStand nextStand(Player pl, Move move) const
    {
      assert(move.isNormal());
      PieceStand result = *this;
      if (move.player() == pl)
      {
	if (const Ptype ptype = move.capturePtype())
	{
	  result.add(unpromote(ptype));
	}
	else if (move.isDrop())
	{
	  const Ptype ptype = move.ptype();
	  assert(get(ptype));
	  result.sub(ptype);
	}
      }
      return result;
    }
    const PieceStand nextStand(Move move) const
    {
      return nextStand(move.player(), move);
    }
    const PieceStand previousStand(Player pl, Move move) const
    {
      assert(move.isNormal());
      PieceStand result = *this;
      if (move.player() == pl)
      {
	if (const Ptype ptype = move.capturePtype())
	{
	  const Ptype before = unpromote(ptype);
	  assert(get(before));
	  result.sub(before);
	}
	else if (move.isDrop())
	{
	  const Ptype ptype = move.ptype();
	  result.add(ptype);
	}
      }
      return result;
    }
    const PieceStand previousStand(Move move) const
    {
      return previousStand(move.player(), move);
    }
  };

  inline bool operator==(PieceStand l, PieceStand r)
  {
    assert(! l.testCarries());
    assert(! r.testCarries());
    return l.getFlags() == r.getFlags();
  }
  inline bool operator!=(PieceStand l, PieceStand r)
  {
    return ! (l == r);
  }
  inline bool operator<(PieceStand l, PieceStand r)
  {
    assert(! l.testCarries());
    assert(! r.testCarries());
    return l.getFlags() < r.getFlags();
  }
  std::ostream& operator<<(std::ostream&, PieceStand l);
} // namespace osl

#endif /* OSL_PIECESTAND_H */
// ;;; Local Variables:
// ;;; mode:c++
// ;;; c-basic-offset:2
// ;;; End: