もなーのあれこれ

血に飢えたハムスターに飢えたあかちゃん

【アズレン攻略wiki】똥 구멍 이구아나 결국 무너져 버린다!!!【続きはこちら】

はじめに

f:id:Monaaaaa:20200504060453p:plain

作るぞ作るぞ作るぞ作るぞ作るぞ!!!!!!!!!!!!!!



在宅期間中暇なので(むむむ???)久しぶりにシコシコ作ります。

とGW前の木曜日に考えていたのですが、
翌日の金曜日の朝にチンコ搔きながら煙キャンディー(配慮表現)なめてたら
電話かかってきて急遽午後から出勤になりました、サイコ~~(^^♪





で、会社で仕事するフリしながらガワだけ作ってました。(強者)

f:id:Monaaaaa:20200504062243p:plain

データグリッドビューのサイズとか列幅とかは最後に適当に調整します。
下に謎の空間があるのは頭が病気だからです。

f:id:Monaaaaa:20200504071740p:plain


↑みたいな感じでファイル選択ダイアログからCSV読み込んでフォーム上に表示させる感じです。

それではさっそくSample1.csvを読み込んでみましょう。(急に何??)







f:id:Monaaaaa:20200504063515p:plain


おお~
とても強そうなデッキが読み込まれましたね?

今回CSVファイルの操作にはCsvHelperというライブラリを使用しました。
オブジェクトとのマッピングなんかも簡単にできるのでとても良いと思いました。(感想文)

FileIO.cs

class FileIO
    {
        private string TargetPath;

        public FileIO(string targetPath)
        {
            this.TargetPath = targetPath;
        }

        public ArrayList ReadCsv()
        {
            var results = new ArrayList();
            using (var fileReader = new StreamReader(TargetPath, Encoding.GetEncoding("utf-8")))
            using (var csvReader = new CsvReader(fileReader, CultureInfo.InvariantCulture))
            {
                csvReader.Configuration.RegisterClassMap<CardDataMapper>();
                csvReader.Configuration.HasHeaderRecord = true;

                foreach (var item in csvReader.GetRecords<CardData>())
                {
                    results.Add(item);
                }
            }
            return results;
        }

        public void WriteCsv(ArrayList arrayList)
        {
            using (var fileWriter = new StreamWriter(TargetPath, false, Encoding.GetEncoding("utf-8")))
            using (var csvWriter = new CsvWriter(fileWriter, CultureInfo.InvariantCulture))
            {
                csvWriter.Configuration.HasHeaderRecord = true;
                csvWriter.Configuration.RegisterClassMap<CardDataMapper>();
                
                csvWriter.WriteRecords(arrayList);
            }
        }
    }


CardData.cs

 class CardData
    {
        public string CardName { get; set; }
        public int CardCount { get; set; }
    }

CardDataMapper.cs

class CardDataMapper : ClassMap<CardData>
    {
        public CardDataMapper()
        {
            Map(x => x.CardName).Name("カード名");
            Map(x => x.CardCount).Name("枚数");
        }
    }


Sample1.csv

"カード名","枚数"
"強欲な壺","39"
"ゴブリンスクラム","1"


ただデータグリッドビュー上のデータをCSVに出力する際にダブルクォートを付ける方法が
公式読んでもよくわかりませんでした。というかハロー以外の英語わかりません。(ドン!!!!!)


とりあえず今後は枚数列のセルをスピンボタン付きのセルにしたいと考えていますが
どうやらそんなものは標準の機能としては無いようでカスタムコントロールとして自分で作らないといけないっぽいです。


あと肝心なトップから引いてくる確率も表示しないといけませんが痴呆なので3日後くらいには忘れていそう。

まぁしばらくコロナで快適在宅キャンペーンが続きそうなので適当に作っていきます。(完)

本編

f:id:Monaaaaa:20200504065836p:plain

..................................................ウム

MP13000でわりと余裕がありました。
次弾でも刺身にたんぽぽを載せるかのようなデッキが強ければ狙えるかね。



最近気に入ってる構築貼っておきます。


式神ウィッチ
f:id:Monaaaaa:20200504070537p:plain


クオンのちんぽしゃぶっとけば勝ちます。





機械自然ドラゴン
f:id:Monaaaaa:20200504070747p:plain


ヴァイディのちんぽしゃぶりながら神のケツ掘っておけば勝ちます。


構築とは関係ないですが、こないだレートの対戦相手に「バトルシャドウバース!!!」とチャット送ったら普通にシカトされました(泣)

アズールレーン

f:id:Monaaaaa:20200504071232j:plain

ニチャァ.......................................................

【アズレン完全攻略wiki】ホロライブコラボキタ━━━━(゚∀゚)━━━━!!おまいらキューブはいくつ貯めてる?【みんなの反応まとめ】

はじめに

前回の続きです。(え????????????)


ストリーム開けなかったらfalseを返す関数を実装して書き込みスレッド側がファイルにアクセスしてるかどうかを調べようとしてましたが、後で調べてみたら排他制御をおこなうためのlockステートメントというものが存在しているらしいです。

同じオブジェクトに対してロックされたブロック内の処理が競合しないとかなんかそんな感じです。

んで前回のFileRWクラスが下記みたいな感じでしたが

FileRW.cs (修正前)

class FileRW
    {
        public String targetfile { get; set; }
        public FileRW(String targetfile)
        {
            this.targetfile = targetfile;
        }
        /// <summary>
        /// テキストファイル書き込み
        /// </summary>
        /// <param name="value">テキスト文字列</param>
        public void FileWrite(String value)
        {
            try
            {
                using (var fs = new FileStream(targetfile, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))
                using (var sw = new StreamWriter(fs))
                {
                    Thread.Sleep(5000); //アクセス競合のためにわざと止まる。
                    sw.WriteLine(value);
                }
            }
            catch (Exception e)
            {

            }
        }
        /// <summary>
        /// テキストファイル読み込み
        /// </summary>
        /// <returns></returns>
        public String FileRead()
        {
            String result;
            try
            {
                using (var fs = new FileStream(targetfile, FileMode.Open, FileAccess.Read, FileShare.None))
                using (var sr = new StreamReader(fs))
                {
                    result = sr.ReadLine();
                }

            }
            catch (Exception e)
            {
                result = "ERROR!";
            }
            return result;
        }
    }

lockステートメントを追加しました。

FileRW.cs (修正後)

    class FileRW
    {
        public String targetfile { get; set; }
        private static Object lockobject = new Object();
        public FileRW(String targetfile)
        {
            this.targetfile = targetfile;
        }
        /// <summary>
        /// テキストファイル書き込み
        /// </summary>
        /// <param name="value">テキスト文字列</param>
        public void FileWrite(String value)
        {
            try
            {
                lock (lockobject)
                {
                    using (var fs = new FileStream(targetfile, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))
                    using (var sw = new StreamWriter(fs))
                    {
                        Thread.Sleep(5000); //アクセス競合のためにわざと止まる。
                        sw.WriteLine(value);
                    }
                }
            }
            catch (Exception e)
            {

            }
        }
        /// <summary>
        /// テキストファイル読み込み
        /// </summary>
        /// <returns></returns>
        public String FileRead()
        {
            String result;
            try
            {
                lock (lockobject)
                {
                    using (var fs = new FileStream(targetfile, FileMode.Open, FileAccess.Read, FileShare.None))
                    using (var sr = new StreamReader(fs))
                    {
                        result = sr.ReadLine();
                    }
                }

            }
            catch (Exception e)
            {
                result = "ERROR!";
            }
            return result;
        }
    }

動かしてみて

f:id:Monaaaaa:20191124221032p:plain

動作ヨシ

まぁ私如きが悩むことはみんな悩んでて解決法も用意されているということですね。

忘れた頃に備忘録を書く漢

本編

うおおおおおおおおおおおおおおおおおお!!!!!!!!!!!!!!!

最近ハマっているゲームがあるます。

f:id:Monaaaaa:20191124222009p:plain

こりがマリオカートちゃんですか??
毎日シコシコ走ってるせいで会社で廊下を曲がるときもイン付きを意識してしまいます。職業病ですね。

最近界隈でひとつの指標とされるようなタイムを出せたのでご報告いたします。

スーパー どろぬまアリーナ 3:00:00切り
f:id:Monaaaaa:20191124222600p:plain

こちら ロボットよこちょう 2:30:00切り
f:id:Monaaaaa:20191124222816p:plain

ひと月前くらいまではランク3桁乗るぞうおおおお!!つってひたすらトライアルしてましたがそろそろ2桁目指したくなりました。(完)

転職時に履歴書の資格欄にクラッシュ・バンディクーレーシング黒帯(クソデカフォント)と書けるように頑張りたいです。

【アズレン完全攻略wiki】初心者必見!!イベント「黒鉄の楽章、誓の海」無課金周回編成はこれで決まり!!

はじめに

マルチスレッドプログラミングでファイルを扱う話。
ファイルに複数スレッドから同時にアクセスするとデータの整合性が取れなかったりするので基本的にはロックを掛けることが多いかと思います。

そんなこんなでこないだ悩む羽目になったので今日の記事

複数スレッドから書き込みと読み込みを同時に行うサンプルが↓

form1.cs

public partial class Form1 : Form
    {
        #region "コンストラクタ"
        public Form1()
        {
            InitializeComponent();
            threadflag = false;
            if (!Directory.Exists("test"))
            {
                Directory.CreateDirectory("test");
            }
        }
        #endregion

        #region "イベントハンドラ"
        private void startbutton_Click(object sender, EventArgs e)
        {
            threadflag = true;
            var wt = new Thread(new ThreadStart(WriteThreadMethod));
            var rt = new Thread(new ThreadStart(ReadThreadMethod));
            wt.Start();
            rt.Start();
        }
        private void stopbutton_Click(object sender, EventArgs e)
        {
            threadflag = false;
        }
        #endregion

        #region "サブスレッド用メンバ"
        /// <summary>
        /// スレッド終了フラグ
        /// </summary>
        private Boolean threadflag;
        /// <summary>
        /// ファイル書き込みスレッド用
        /// </summary>
        private void WriteThreadMethod()
        {
            while (threadflag)
            {
                var filename = $"{DateTime.Now.ToString("yyyyMMddHHmmss")}.txt";
                var textvalue = DateTime.Now.ToString();
                var frw = new FileRW($@"test\{filename}");
                frw.FileWrite(textvalue);
                Thread.Sleep(1000);
            }
        }
        /// <summary>
        /// ラベル更新用デリゲート
        /// </summary>
        /// <param name="value">テキスト</param>
        private delegate void labeldelegate(String value);
        /// <summary>
        /// ファイル読み込みスレッド用
        /// </summary>
        private void ReadThreadMethod()
        {
            var di = new DirectoryInfo("test");
            while (threadflag)
            {
                foreach (FileInfo fi in di.GetFiles())
                {
                    var frw = new FileRW(fi.FullName);
                    if (InvokeRequired)
                    {
                        this.Invoke(new labeldelegate((String text) => { textlabel.Text = text; }), new Object[] { frw.FileRead() });
                    }
                    else
                    {
                        textlabel.Text = frw.FileRead();
                    }
                    Thread.Sleep(500);
                }
            }
        }
        #endregion
    }


FileRW.cs

class FileRW
    {
        public String targetfile { get; set; }
        public FileRW(String targetfile)
        {
            this.targetfile = targetfile;
        }
        /// <summary>
        /// テキストファイル書き込み
        /// </summary>
        /// <param name="value">テキスト文字列</param>
        public void FileWrite(String value)
        {
            try
            {
                using (var fs = new FileStream(targetfile, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None))
                using (var sw = new StreamWriter(fs))
                {
                    Thread.Sleep(5000); //アクセス競合のためにわざと止まる。
                    sw.WriteLine(value);
                }
            }
            catch (Exception e)
            {

            }
        }
        /// <summary>
        /// テキストファイル読み込み
        /// </summary>
        /// <returns></returns>
        public String FileRead()
        {
            String result;
            try
            {
                using (var fs = new FileStream(targetfile, FileMode.Open, FileAccess.Read, FileShare.None))
                using (var sr = new StreamReader(fs))
                {
                    result = sr.ReadLine();
                }

            }
            catch (Exception e)
            {
                result = "ERROR!";
            }
            return result;
        }
    }

時間をテキストファイルに次々出力していくスレッドと、出力されたテキストファイルを読み込んでいってテキストファイルの内容でラベルを更新していくって感じです。

ただ上記ソースだと書き込み中のファイルに対して読み込みを行うと別のプロセスが~とか言われて読み込めないタイミングがあるます。

f:id:Monaaaaa:20190525140932p:plain

こんな感じ。(どんな感じ?)

ReadFile()の前にファイルにアクセスできるかどうか調べてぇな...となったんだけど、FileInfoクラスにそういったプロパティとかメソッドないっぽい?ので

FileRWクラスに下記メソッドを追加して

        /// <summary>
        /// ファイルアクセス可否判定
        /// </summary>
        /// <returns>true→アクセス不可、false→アクセス可能</returns>
        public Boolean FileIsLocked()
        {
            try
            {
                using (var fs = new FileStream(targetfile, FileMode.Open, FileAccess.Read, FileShare.None))
                {
                }
            }
            catch(Exception e)
            {
                return true;
            }
            return false;
        }

Form1クラスのReadThreadMethod()内でファイルを読み込む直前に↓みたいな感じで待機する風に書き換えました。

       private void ReadThreadMethod()
        {
            var di = new DirectoryInfo("test");
            while (threadflag)
            {
                foreach (FileInfo fi in di.GetFiles())
                {
                    var frw = new FileRW(fi.FullName);

                    //アクセス不可だったら少し待つ
                    while (frw.FileIsLocked() == true) Thread.Sleep(500);

                    if (InvokeRequired)
                    {
                        this.Invoke(new labeldelegate((String text) => { textlabel.Text = text; }), new Object[] { frw.FileRead() });
                    }
                    else
                    {
                        textlabel.Text = frw.FileRead();
                    }
                    Thread.Sleep(500);
                }
            }
        }

これで後続のアクセスが書き込み中のプロセスを待つような処理が実現できました(完)
まぁ、この記事の方法だと別の理由でファイルにアクセスできなかった場合すべてが崩壊するんだけどね(照)

なんかいい方法ないですかね~♨

というわけで今日のおまけはここまでです。

本編

アズレンやってるかい?

僕はシャドウバースばかりしてました///
僕がアズレンから逃げたというよりはアズレンが俺から逃げていったといった感じでしょうか。

ですがシャドウバースでボコボコにされすぎて頭がおかしくなってアズレン再開しました。(パチパチパチ)

f:id:Monaaaaa:20190525143938j:plain

UIが色々変わりすぎてワロタです。

こういう金にならないところも頑張ってくれるの普通にいいですね。
キズナアイはカスだけど。

で、前回のあちゃちゃんと今回のビスマルク追加で鉄血陣営の主力艦隊増えて良かったなぁと思います。
ホントこのままだとどうやってガスコーニュとかフリードニヒ解禁するんだって感じだったので。

今回のイベントで解禁目指したいです。

おわりに

あかご
f:id:Monaaaaa:20190525145013j:plain

【アズレン攻略】キズナアイコラボが遂にキタ━(゚∀゚)━!おまいらどんな編成で周回する?www【みんなの反応まとめ】

はじめに

GWめっちゃ暇だったのでASP.NET MVCでwebアプリ作ろうとしました。
シコシコ作ったログイン画面がこちら

f:id:Monaaaaa:20190509213100p:plain

これマジ?テンプレートに比べて 実装が貧弱過ぎるだろ・・・・・
MVCテンプレートに入ってたcssとか使ってとりあえずそれっぽい見た目のものを作りました。

 [HttpPost]
        public ActionResult Login(UserInfoForm userInfo)
        {
            if (!Common.txtValueCheck(userInfo))
            {
                ViewBag.Result = "IDもしくはパスワードが無効です。";
                return View("/Views/Login/Index.cshtml");
            }

            var userInfoDB = new UserInfoDB();
            userInfoDB = userInfoDB.findUserInfoDB(userInfo);
            if (String.IsNullOrEmpty(userInfoDB.UserID))
            {
                ViewBag.Result = "ログイン認証に失敗しました。";
                return View("/Views/Login/Index.cshtml");
            }
            FormsAuthentication.SetAuthCookie(userInfoDB.UserID, true);
            Response.Cookies["uid"].Value = userInfoDB.UserID;
            return Redirect("/User/Index?UserID=" + Server.UrlEncode(userInfoDB.UserID)); 
        }

フォームに入力されたIDとパスワードをUserInfoFormクラスの変数にぶち込んでDBに検索かけて
レコードが見つかれば認証するといった感じの縄文時代から伝わるフォーム認証といった感じです。

ログイン後もIDは使いまわしたいのでとりあえずクッキーに書き込んでみたりリクエストパラメータにぶち込んでみたりしてます。

勉強していく上で必要なくなったらクッキーかリクエストパタメータのどちらかは消すかも知れない。

とここまで作ってみたところで認証後であればURL直打ちで別サイトからでもログイン後のページにもアクセスできてしまうことに気づいた。

あんまよくないよなぁ...

アクセス制限

ログイン後のページに直接アクセスされるのはそこそこ困るので調べるとWeb.configでアクセス制限できるっぽいね。

    <authentication mode="Forms">
      <forms loginUrl="/Login"/>
    </authentication>

要素内に上記のように書くことで認証が必要なページにアクセスしようとした際にログインページにリダイレクトするようになりました。

<location path="User">
      <system.web>
        <authorization>
          <deny users="?"/>
        </authorization>
      </system.web>
    </location>

ついでに匿名のアクセスを禁止する設定も書いておきます。

f:id:Monaaaaa:20190509215525p:plain
この状態で↑のようにUser/Index(ログイン後のページ)にアクセスしようとすると

f:id:Monaaaaa:20190509215557p:plain
ログインページに勝手に飛ばされちゃいます。

これだけのことやるのにめっちゃ時間かかったし頭も痛くなったしもう全てが嫌になった。

ほんへ

かなり怒っている、キズ○アイさんコラボクソすぎるだろ。

f:id:Monaaaaa:20190509220220j:plain

まぁ全部引くんですけどね(^^;)
ただこれのせいで別の期間限定引ききれなくて血管ちぎれました。

しかもマップに出てくる敵のレベルが80台で金設計図もまったく美味くないという

小遣い稼ぎの為にアズレンやってる女のせいで、アズレン運営に小遣いやってるおれが苦しんでるんだが

というわけで次回は怒りの13章攻略記事を書きたいと思います...
ほなまた

追伸

f:id:Monaaaaa:20190509221006j:plain
あかちゃん

【アズレン完全攻略wiki】Invokeメソッドを使ったサブスレッドからのフォーム操作

はじめに

どぅも~モナ↑ーでぇす。ハイ、というわけでね、C#の方やっていきたいと思いまスゥ...

おま○け

別スレッドからフォームを操作したいということがあって【初心者必見!】みたいなサイト見ながら頑張ってプログラム書いてたんだけどうまくいかなかった。

f:id:Monaaaaa:20190317111133p:plain

別スレッドで行った処理の結果をフォームに表示させるみたいな。
ちなみに思い描いてるものとしては画面右のスタートボタン押すと左側のラベルが1,2,3,4,......100までカウントアップしていくって感じのものです。
ソースは↓です。

public partial class Form1 : Form
    {
        delegate void CountDlg();

        public Form1()
        {
            InitializeComponent();
        }

        private void StartButton_Click(object sender, EventArgs e)
        {
            var thread = new Thread(new ThreadStart(CountThread));
            thread.Start();
        }

        private void CountThread()
        {
            CountDlg count = () =>
            {
                for (var i = 1; i <= 100; i++)
                {
                    label1.Text = i.ToString();
                    Thread.Sleep(100);
                }
            };

            this.Invoke(count);
        }
}

ちなみにこれを動かすとスタートボタン押した瞬間Formアプリケーションくん迫真の”応答なし”で応戦してくれます。嬉しい。(嘘です。めっちゃキレそうになりました。)そしていきなり表示が100になって頭が爆発します。

そしてセコセコ修正したのが↓

 public partial class Form1 : Form
    {
        delegate void CountDlg();

        public Form1()
        {
            InitializeComponent();
        }

        private void StartButton_Click(object sender, EventArgs e)
        {
            var thread = new Thread(new ThreadStart(CountThread));
            thread.Start();
        }

        private void CountThread()
        {
            for (var i = 1; i <= 100; i++)
            {
                UpdateText(i);
                Thread.Sleep(500);
            }
        }

        private void UpdateText(int value)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new CountDlg(() => label1.Text = value.ToString()));
            }
            else
            {
                label1.Text = value.ToString();
            }
        }
    }

デリゲートが参照する処理の中ではラベルの更新だけ行ってカウントアップの処理は
CountThreadの中で行うようにしたらうまくいきました。

なんででしょうかねぇ...不思議ですねぇ...

Visual Studioさんが便利すぎてフォームアプリの内部的なことをあまり理解できてないのかなというのがすごく実感できたので暇なときに(いつ??)調べようと思いました。

本編

f:id:Monaaaaa:20190317114132p:plain

そろそろ俺を試そうとするのはやめませんか?

lv65程度の敵しかわかないマップを60週もさせられる俺の気持ちわかるか?言ってることわかるか??

まぁ”廻る”んですけどね。

f:id:Monaaaaa:20190317114448p:plain

ちょうどシャングリラのレベルが良い感じなので、こいつのレベリングなんだと自分に言い聞かせながら周回しているような状況です。

とはいってもかなりしんどいので次のイベントもゲロマズだったらシャドウバースガチ勢にジョブチェンジするかもしれません。

ほなまた...

追伸

じろうさんのブログにてもなーのあれこれを紹介していただきました。
ありがとうございます。

栄光のセラフラピス

はじめに

今日からオナ禁します。(おぉ~~!)

来月

来月はシャドウバースします(ドン!)
なぜなら持病をこじらせて課金したからであります(T_T)

というのは冗談で(課金したのはマジだが)本当のところはだいぶ前に作ったシャドウバースの戦績記録用のフォームアプリを使いたかったから

f:id:Monaaaaa:20190130210407p:plain

”””見ただけでは使い方がわからない神懸かったUI”””

上のほうは試合結果の送信とその日の(というのは真っ赤な嘘でアプリを立ち上げてから×ボタン押して終了するまでの間)の戦績です。
勝数と負け数をアプリのほうで保持して勝率出してくれます。

ボタンに「送信」って書いてあるのは↓みたいな感じで自宅のDBサーバーに戦績を送信しているから。

f:id:Monaaaaa:20190130210818p:plain

こっちのほうでは1か月分の戦績を蓄積してくれます。
そして下のほう(グラフとかそこらへん)の方は逆にサーバーのほうから過去の戦績を引っ張て来てグラフ化して表示してくれます。

一枚目の画像だと「自分がビショップ使って先攻だった時、ウィッチには100%勝ってるけどそれ以外のクラス相手には100%負けてるよ^^」ということになります。

ちなみにこっちのほうのボタンに「送信」と書かれているのは俺がマジもんのバカで日本語が不自由だからです。

ニチャァ...

f:id:Monaaaaa:20190130211816p:plain

語るまでもなく「陰」です。

まじでテッペン目指します。

おわりに

オナ禁終了~~!! (記事書くの途中で飽きてマスかきました///)

[記録:57分]

\\New Record!!// マリーティー



~完~