【C#】【ALTSEED】【数独】9×9マスの外をクリックしてもパレットが表示されてしまう動作の修正

前回までの状況はこちら。

最新ソースはこちら(gitHub)

https://github.com/takishita2nd/sudokuGUI

やることの一つ目を解決します。

9×9の範囲が分かれば、対処は簡単です。

9×9は画像なので、幅、高さはプロパティを見ればわかります。

        private const int width = 576;
        private const int height = 576;

これが分かれば、isClick()を作成。

        private bool isClick(asd.Vector2DF pos)
        {
            if (pos.X > offsetX && pos.X < offsetX + width &&
                pos.Y > offsetY && pos.Y < offsetY + height)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

これを使用します。

                        if (isButtonClisk == false)
                        {
                            if (isClick(pos) == true)
                            {
                                mouseHold = true;
                                palette.show(pos);
                                for (int row = 0; row < 9; row++)
                                {
                                    for (int col = 0; col < 9; col++)
                                    {
                                        if (squareObjects[row, col].isClick(pos) == true)
                                        {
                                            clickedSquareObject = squareObjects[row, col];
                                        }
                                    }
                                }
                            }
                        }

こんな感じでどうでしょうか。

【バンドリ】【ガルパ】4/24のハロハピ放送局で公開された情報まとめ

新情報まとめました。

新カバー楽曲

UNIONはO×Tが2018年11月にリリースされた曲で、アニメ「SSSS.GRIDMAN」のOPでした。

Poppin’Partyのカバーで実装されます。

予想レベル25。

秒針を噛むはずっと真夜中で良いのに。が2018年6月にYouTubeで公開された曲です。

予想レベル26。

ゲーム内イベント

5/3に開催予定だったガルパーティ2020に合わせてゲーム内でもイベントが実施されます。

うーむ、仕方が無いとは言え、悔しい・・・。

追加バンド

追加バンドRASの情報も公開されました。

6月のイベントにてバンドイベント公開ということは、それより前に実装が確実のようです。

5月実装説ありえるぞ。

RAS実装に先行して楽曲も25日に追加されます。

予想レベル25。

リモートで放送するというのも新鮮でありなのですが、

早くコロナ収まって欲しいですね。

【C#】【ALTSEED】【数独】これからやること。

前回までの状況はこちら。

とりあえず、解析処理を行い、結果を表示するところまで完成しましたが、これだけではまだツールとしては完成ではありません。

まだまだ手を加えなければならないところがあります。

それは以下の3つです。

  • 9×9マスの外をクリックしてもパレットが表示されてしまう動作の修正
  • (入力データのミスで)解析ができなかった場合の対処
  • そもそも解析前の入力データに誤りがあった場合の対処

こんなところですかね。

具体的にどう対応するかはおいおい考えるとして、

まずは簡単に対処できそうな所から対処していこうと思います。

【C#】【ALTSEED】【数独】解析処理を実行

前回までの状況はこちら。

最新ソースはこちら(gitHub)

https://github.com/takishita2nd/sudokuGUI

解析処理を実行する処理を作成します。

作り方は前回のクリアボタンと同じです。

Buttonクラスを継承して、AnalyzeButtonクラスを作成します。

    class AnalyzeButton : Button
    {
        public AnalyzeButton() : base(600, 570, "解析開始")
        {

        }

        public override void onClick(SquareObject[,] squareObjects)
        {
            Square[,] squares = new Square[9, 9];
            for (int row = 0; row < 9; row++)
            {
                for (int col = 0; col < 9; col++)
                {
                    squares[row, col] = new Square(squareObjects[row, col].getValue(), row, col);
                }
            }
            Sudoku sudoku = new Sudoku(squares, null);
            sudoku.run();
            for (int row = 0; row < 9; row++)
            {
                for (int col = 0; col < 9; col++)
                {
                    squareObjects[row, col].setValue(squareObjects[row, col].getValue());
                }
            }
        }
    }

これを実装します。

            // ボタン
            List<Button> buttons = new List<Button>();
            Button clear = new ClearButton();
            asd.Engine.AddObject2D(clear.getBackTexture());
            asd.Engine.AddObject2D(clear.getTextObject());
            buttons.Add(clear);

            Button start = new AnalyzeButton();
            asd.Engine.AddObject2D(start.getBackTexture());
            asd.Engine.AddObject2D(start.getTextObject());
            buttons.Add(start);

            // パレット
            palette = new Palette();
            palette.setEngine();




            // Altseedが進行可能かチェックする。
            while (asd.Engine.DoEvents())
            {
                asd.Vector2DF pos = asd.Engine.Mouse.Position;
                if (!mouseHold)
                {
                    for (int row = 0; row < 9; row++)
                    {
                        for (int col = 0; col < 9; col++)
                        {
                            squareObjects[row, col].updateTexture(pos);
                        }
                    }
                    foreach(Button button in buttons)
                    {
                        button.updateTexture(pos);
                    }
                }
                else
                {
                    palette.updateTexture(pos);
                }

                if (asd.Engine.Mouse.LeftButton.ButtonState == asd.ButtonState.Push)
                {
                    if (mouseHold)
                    {
                        if (!palette.isClick(pos))
                        {
                            palette.hide();
                            mouseHold = false;
                        }
                        else
                        {
                            int value = palette.getClickValue(pos);
                            if(clickedSquareObject != null)
                            {
                                clickedSquareObject.setValue(value);
                                palette.hide();
                                mouseHold = false;
                            }
                        }
                    }
                    else
                    {
                        bool isButtonClisk = false;
                        foreach (Button button in buttons)
                        {
                            if (button.isClick(pos))
                            {
                                button.onClick(squareObjects);
                                isButtonClisk = true;
                            }
                        }

                        if (isButtonClisk == false)
                        {
                            mouseHold = true;
                            palette.show(pos);
                            for (int row = 0; row < 9; row++)
                            {
                                for (int col = 0; col < 9; col++)
                                {
                                    if (squareObjects[row, col].isClick(pos) == true)
                                    {
                                        clickedSquareObject = squareObjects[row, col];
                                    }
                                }
                            }
                        }
                    }
                }

                // Altseedを更新する。
                asd.Engine.Update();
            }

各種ボタン系はButtonリストでまとめておき、updateTexture()、isClick()、onClick()処理をforeachでまとめて処理できるように修正しています。

これで解析までできるはず。

ん?

あああ!

今の解析処理、解析結果をテキストに吐き出す処理のままだった!

これは解析処理にも修正をいれなくては。。。

ここまで来たので、修正しました。

あああ、この瞬間がたまらない!

これこそがプログラマーの喜び!

PC版のアリスギアアイギスがパワーアップしていたんだが。

最近リリースされたらしい。

今までは仮想環境にスマホをエミュレートしていた感じで動作していたのですが、

新しいクライアントソフトは完全にPC用に作られたものです。

まずホーム画面。

広い。

スマホの画面が横に二つ付いたような画面の広さ。

そして、待望の、ゲームパッド対応。

PC用のコントローラーで操作できます。

操作方法はこんな感じ。

キーバインドで配置を変更できます。

あと、左スティックで仮想カーソルを動かすこともできますが、マウスの方が早いので、戦闘以外はそちらの方が良いと思います。

それでは、白熱のバトルの様子をご覧ください。

これはもうスマホには戻れんわ。

ちょっと最近は放置気味だったけど頑張ってみるか。

あなたは3密を避けるという意味を間違えていないか?

昨日ニュースを見ていたら、とある、発信力のある方が

「パチンコは空調設備が整っているから換気が良いので、3密では無いから安全」

と言っているので、それに対して「待った!」と言いたい。

あなたは3密で無ければコロナに感染しないと思っているのではないか?

それは大きな間違い。

昨日の夕方の専門家が言っていた。

公園などに外出して、子連れのママ達が集まって会話した場合、換気は良いが、密集、密接しているので、飛沫感染する可能性はある、と。

パチンコ屋だって、人が一箇所に密集しているではないか。

3密のうち、一つでも密があると、感染するリスクは存在する。

密が重なると、感染する確率が高くなるだけ。

感染するリスクを0にするためには、3密を完全に排除するしか無い。

ついでに言っておくと、東京で感染経路が分からない人達は通勤電車の中で感染しているんじゃないかと思います。

会社の経営者は、電車以外の通勤手段を手配するとか、会社の近くにホテルを取るとかして、社員の安全を確保するために手を尽くさなければあとで大きなリスクを背負うことになりますよ。

【C#】【ALTSEED】【数独】ボタン作成

前回までの状況はこちら。

最新ソースはこちら(gitHub)

https://github.com/takishita2nd/sudokuGUI

処理を行うボタンを設置します。

作成するボタンは「解析開始」ボタンと、入力した数字を全部消去する「クリア」ボタンです。

まず、ボタンを配置するところから作ります。

ボタンを配置するためにボタン用のクラスを作成します。

しかし、すでに作成しているSquareObjectクラスと重複している部分があるので、新たにObjectBaseクラスを作成して、共通部分はこちらに書きます。

    class ObjectBase
    {
        protected int _x;
        protected int _y;
        protected asd.TextureObject2D _backTexture;
        protected asd.TextObject2D _valueText;
        protected int width;
        protected int height;

        public asd.TextureObject2D getBackTexture()
        {
            return _backTexture;
        }

        public asd.TextObject2D getTextObject()
        {
            return _valueText;
        }

        public bool isClick(asd.Vector2DF pos)
        {
            if (pos.X > _x && pos.X < _x + width
                && pos.Y > _y && pos.Y < _y + height)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }

そして、SquareObjectクラスと新たに作成するボタンクラスはこのObjectBaseクラスを継承します。

SquareObjectの記載は省略します。gitHubのソースを参照してください。

    class Button : ObjectBase
    {
        private string _text;
        private const int fontOffsetX = 39;
        private const int fontOffsetY = 9;

        public Button(int x, int y, string text)
        {
            width = 256;
            height = 64;
            _x = x;
            _y = y;
            _text = text;

            _backTexture = new asd.TextureObject2D();
            _backTexture.Position = new asd.Vector2DF(_x, _y);

            _valueText = new asd.TextObject2D();
            _valueText.Text = _text;
            _valueText.Font = Resource.getTextFont();
            _valueText.Position = new asd.Vector2DF(_x + fontOffsetX, _y + fontOffsetY);
        }

        public void updateTexture(asd.Vector2DF pos)
        {
            if (pos.X > _x && pos.X < _x + width
                && pos.Y > _y && pos.Y < _y + height)
            {
                _backTexture.Texture = Resource.getButtonTexture();
            }
            else
            {
                _backTexture.Texture = null;
            }
        }

        public virtual void onClick(SquareObject[,] squareObjects)
        {
            throw new NotImplementedException();
        }
    }

onClick()にクリック時の処理を記載します。

実際はこのクラスを継承して使用するので、ここでは未実装Exceptionを投げて例外を発生させます。

このクラスを継承して、まずはクリア処理を作成します。

    class ClearButton : Button
    {
        public ClearButton() : base(600, 500, "クリア")
        {

        }

        public override void onClick(SquareObject[,] squareObjects)
        {
            for (int row = 0; row < 9; row++)
            {
                for (int col = 0; col < 9; col++)
                {
                    squareObjects[row, col].setValue(0);
                }
            }
        }
    }

これを使用して、処理を作成します。

            // ボタン
            Button clear = new ClearButton();
            asd.Engine.AddObject2D(clear.getBackTexture());
            asd.Engine.AddObject2D(clear.getTextObject());

            Button start = new Button(600, 570, "解析開始");
            asd.Engine.AddObject2D(start.getBackTexture());
            asd.Engine.AddObject2D(start.getTextObject());

            // Altseedが進行可能かチェックする。
            while (asd.Engine.DoEvents())
            {
                asd.Vector2DF pos = asd.Engine.Mouse.Position;
                if (!mouseHold)
                {
                    for (int row = 0; row < 9; row++)
                    {
                        for (int col = 0; col < 9; col++)
                        {
                            squareObjects[row, col].updateTexture(pos);
                        }
                    }
                    clear.updateTexture(pos);
                    start.updateTexture(pos);
                }
                else
                {
                    palette.updateTexture(pos);
                }

                if (asd.Engine.Mouse.LeftButton.ButtonState == asd.ButtonState.Push)
                {
                    if (mouseHold)
                    {
                        if (!palette.isClick(pos))
                        {
                            palette.hide();
                            mouseHold = false;
                        }
                        else
                        {
                            int value = palette.getClickValue(pos);
                            if(clickedSquareObject != null)
                            {
                                clickedSquareObject.setValue(value);
                                palette.hide();
                                mouseHold = false;
                            }
                        }
                    }
                    else
                    {
                        if (clear.isClick(pos))
                        {
                            clear.onClick(squareObjects);
                        }
                        else
                        {
                            mouseHold = true;
                            palette.show(pos);
                            for (int row = 0; row < 9; row++)
                            {
                                for (int col = 0; col < 9; col++)
                                {
                                    if (squareObjects[row, col].isClick(pos) == true)
                                    {
                                        clickedSquareObject = squareObjects[row, col];
                                    }
                                }
                            }
                        }
                    }
                }

                // Altseedを更新する。
                asd.Engine.Update();
            }

実行結果はこんな感じ。

次回は解析処理を実装していきます。

【C#】【ALTSEED】【数独】パレットから数字を入力する

前回までの状況はこちら。

最新ソースはこちら(gitHub)

https://github.com/takishita2nd/sudokuGUI

今回でパレット処理を完成させます。

パレットの数字をクリックしたら、そのパレットマスの数字を取得して、パレットを消去し、マスに数字を入力します。

まずは、パレットのどのマスがクリックされたかを確認します。

これはSquareObjectに実装します。

    public bool isClick(asd.Vector2DF pos)
    {
        if (pos.X > _x && pos.X < _x + width
            && pos.Y > _y && pos.Y < _y + height)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

やっていることはupdateTexture()と同じで、マウスカーソルがマスの中にあるかどうかを判定して、true/falseを返します。

そしてもう一つ。

        public int getValue()
        {
            return _value;
        }

こっちは特に説明は入らないですよね。

これをPaletteクラスに実装します。

        public int getClickValue(asd.Vector2DF pos)
        {
            for (int row = 0; row < 3; row++)
            {
                for (int col = 0; col < 3; col++)
                {
                    if(paletteSquareObjects[row, col].isClick(pos) == true)
                    {
                        return paletteSquareObjects[row, col].getValue();
                    }
                }
            }
            if (PaletteBatsuSquareObject.isClick(pos))
            {
                return 0;
            }
            return 0;
        }

isClick()でマウスカーソルがマスの中にあるかを確認して、その中にあればgetValue()で値を取得します。

これを×にも実装し、こちらは空白を意味する0を返します。

これをsudokuUIに実装します。

            // Altseedが進行可能かチェックする。
            while (asd.Engine.DoEvents())
            {
                asd.Vector2DF pos = asd.Engine.Mouse.Position;
                if (!mouseHold)
                {
                    for (int row = 0; row < 9; row++)
                    {
                        for (int col = 0; col < 9; col++)
                        {
                            squareObjects[row, col].updateTexture(pos);
                            if(squareObjects[row, col].isClick(pos) == true)
                            {
                                clickedSquareObject = squareObjects[row, col];
                            }
                        }
                    }
                }
                else
                {
                    //palette.updateTexture(pos);
                }

                if (asd.Engine.Mouse.LeftButton.ButtonState == asd.ButtonState.Push)
                {
                    if (mouseHold)
                    {
                        if (!palette.isClick(pos))
                        {
                            palette.hide();
                            mouseHold = false;
                        }
                        else
                        {
                            int value = palette.getClickValue(pos);
                            if(clickedSquareObject != null)
                            {
                                clickedSquareObject.setValue(value);
                                palette.hide();
                                mouseHold = false;
                            }
                        }
                    }
                    else
                    {
                        mouseHold = true;
                        palette.show(pos);
                        for (int row = 0; row < 9; row++)
                        {
                            for (int col = 0; col < 9; col++)
                            {
                                if (squareObjects[row, col].isClick(pos) == true)
                                {
                                    clickedSquareObject = squareObjects[row, col];
                                }
                            }
                        }
                    }
                }

mouseHold==true(パレット表示中)で、パレットがクリックされた場合、先ほど実装したgetClickValue()を使用して、数値を取得します。

9×9のどこをクリックしたかを覚えておかなければならないため、パレットを表示する際に、どのマスをクリックされたかを覚えておきます。

この覚えたマスに対して、パレットから取得した数値を設定します。

ちなみに、palette.updateTexture(pos)をコメント化しているのは、パレットにもマウスカーソルでテクスチャを適用しようとすると、パレットを消したときにテクスチャが残ってしまうからです。

多分、エンジンのバグ。

なので、パレットにはマウスカーソルでテクスチャ適用は諦めました。

実行結果はこんな感じです。

だいぶ形になってきました。

完成まであと少しです。

購入。Kindle Paperwhite

届きました。

最新モデルのKindle Paperwhite。

世代で言うと第10世代で、Kindle Paperwhiteとしては4代目らしい。

これがリリースされたのが2018年だから2年前なのね。

左が本体。右がカバーです。

今まで使用していたのは、第7世代(Kindle Paperwhite3代目)。

左が今まで使用していたKindle。右が新品。

サイズはほんの少しだけ右の方がコンパクトになっているね。

サイズが変わっているので、カバーも一緒に買っておいて良かった。

Kindleはディスプレイ部分が衝撃に弱いので、手帳型のカバーを買っていた方が長持ちします。

実際に、1回ディスプレイ破れました。

無償で本体を交換してくれましたが。

それがあってから、スマホ・タブレットのケースは手帳型最強説を唱えています。

今回のKindleで何が変わったかというと、

一番大きなところで、防水仕様になりました。

見た目からして、ディスプレイがフラット仕様になっていますね。

お風呂の中での読書もはかどります。

最近半身浴で長時間お風呂に浸かっていることが多いので、防水のKindleが欲しかったんですよね。

あと、本体の容量が4GBから32GBになりました。

Kindleの本のデータサイズはかなり小さくなるように調整されていますが、それでも4GBはあっという間に埋まり、定期的にデータ削除とデータダウンロードを繰り返しています。

Kindleはデータダウンロード時に一番バッテリーを消費するらしいので、あらかじめWi-Fi環境下で充電しながらダウンロードしておくのが一番良いらしいですよ。

一度ダウンロード済ませておけば、ほとんどバッテリー消費すること無く読書を楽しむことができます。

古いKindleはメルカリで売ることにします。

分解するにはもったいないので。

まだまだ十分使えますし。

【C#】【ALTSEED】【数独】パレットに×を追加。

前回までの状況はこちら。

最新ソースはこちら(gitHub)

https://github.com/takishita2nd/sudokuGUI

引き続き、パレットの中身を実装していきます。

パレットに×を追加します。

×のフォントをフォントジェネレータで作成して実装します。

    static class Resource
    {
        private static asd.Font _fontBatsu = null;

        public static asd.Font getFontBatsu()
        {
            if (_fontBatsu == null)
            {
                _fontBatsu = asd.Engine.Graphics.CreateFont("batsu.aff");
            }
            return _fontBatsu;
        }

これを使用します。

クラスは・・・PaletteSquareObjectを拡張しましょうか。

    class PaletteBatsuSquareObject : PaletteSquareObject
    {
        public PaletteBatsuSquareObject(int row, int col) : base(row, col)
        {
            _valueText.Font = Resource.getFontBatsu();
        }

        public void showBatsu()
        {
            _valueText.Text = "×";
        }

        public new void setPosition(asd.Vector2DF pos)
        {
            _x = _row * width + (int)pos.X;
            _y = _col * height + (int)pos.Y;

            _backTexture.Position = new asd.Vector2DF(_x, _y);
            _valueText.Position = new asd.Vector2DF(_x + fontOffsetX - 8, _y + fontOffsetY);
        }
    }

コンストラクタで、フォントを追加した物に指定、showBatsu()で×を表示します。

また、×の表示位置を調整するため、setPosition()をオーバーライドしています。

    class SquareObject
    {

        public void hide()
        {
            _valueText.Text = "";
        }

SquareObjectクラスにhide()を追加しました。これでわかりやすく文字を消すことができます。

これらをPaletteクラスに実装します。

    class Palette
    {
        PaletteBatsuSquareObject PaletteBatsuSquareObject = new PaletteBatsuSquareObject(0, -1);

        public void setEngine()
        {
            asd.Engine.AddObject2D(_texture);
            for (int row = 0; row < 3; row++)
            {
                for (int col = 0; col < 3; col++)
                {
                    asd.Engine.AddObject2D(paletteSquareObjects[row, col].getBackTexture());
                    asd.Engine.AddObject2D(paletteSquareObjects[row, col].getTextObject());
                }
            }
            asd.Engine.AddObject2D(PaletteBatsuSquareObject.getBackTexture());
            asd.Engine.AddObject2D(PaletteBatsuSquareObject.getTextObject());
        }

        public void show(asd.Vector2DF pos)
        {
            palettePosition = new asd.Vector2DF(pos.X, pos.Y - 64);
            _texture.Position = palettePosition;
            _texture.Texture = Resource.getPalette();
            int value = 1;
            for (int row = 0; row < 3; row++)
            {
                for (int col = 0; col < 3; col++)
                {
                    paletteSquareObjects[row, col].setPosition(pos);
                    paletteSquareObjects[row, col].setValue(value);
                    value++;
                }
            }
            PaletteBatsuSquareObject.setPosition(pos);
            PaletteBatsuSquareObject.showBatsu();
        }

        public void hide()
        {
            _texture.Texture = null;
            for (int row = 0; row < 3; row++)
            {
                for (int col = 0; col < 3; col++)
                {
                    paletteSquareObjects[row, col].hide();
                }
            }
            PaletteBatsuSquareObject.hide();
        }

やることは他の文字と同じで、Altseedエンジンへの追加、表示、消去を行います。

実行結果はこんな感じです。

まあまあですかね。

自分、ぼっちですが何か?