Star Wars書いてみた
えーセルオートマトンがそもそも分かってないですがStar Wars書いてみた。
ルールはこちらの説明オンリーで作らせていただきましたありがとうございます。
http://yowaken.dip.jp/tdiary/20081122.html#p02
動きはこちらを見て確認させていただきましたありがとうございます。
セルオートマトンを用いたシューティングゲーム - Tosikの雑記
動いているのを見てて楽しいですね。デフラグずっと見ちゃう的ですね。
実装はIronPython+XNAでやろうと思ったんだけどTexture2Dでのべた矩形がなぜが出なくて。
なので普通にC#+XNAになってます。しかしC#でも同意のコード書いてんのになんで出ないんだ。
#region Using Statements using System; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Storage; #endregion namespace starwars { public class Cell { StarWars parent; public int x; public int y; public int state; int next_state; public Cell(StarWars p, int _x, int _y) { parent = p; x = _x; y = _y; state = 0; next_state = 0; } int count_around(int target_state) { int count = 0; Cell[] a = new Cell[8]; a[0] = parent.get(x - 1, y - 1); a[1] = parent.get(x - 1, y); a[2] = parent.get(x - 1, y + 1); a[3] = parent.get(x, y - 1); a[4] = parent.get(x, y + 1); a[5] = parent.get(x + 1, y - 1); a[6] = parent.get(x + 1, y); a[7] = parent.get(x + 1, y + 1); for (int i = 0; i < 8; i++) { if (a[i] != null && a[i].state == target_state) count++; } return count; } public int reserve_state() { next_state = state; switch (state) {//TODO magic number case 0: if (count_around(1) == 2) next_state++; break; case 1: if (count_around(1) >= 3 && count_around(1) <= 5) { } else { next_state++; } break; case 2: next_state++; break; case 3: next_state = 0; break; } return next_state; } public int update() { return state = next_state; } } public class StarWars{ public Cell[] map; public int width, height; Random rand = new Random(); public StarWars(int _w, int _h) { width = _w; height = _h; map = new Cell[width * height]; } public Cell get(int x, int y) { //回り込み x = (x + width) % width; y = (y + height) % height; if (x < 0 || y < 0 || x >= width || y >= height) return null; return map[y * width + x]; } public Cell get(int i) { return get(i % width, i / width); } public Cell make(int x, int y) { Cell c = new Cell(this, x, y); c.state = rand.Next(3); return map[y * width + x] = c; } public Cell make(int i) { return make(i % width, i / width); } void reserve_state() { for (int i = 0; i < width * height; i++) { if (map[i] != null) { map[i].reserve_state(); } } } public void update() { reserve_state(); for (int i = 0; i < width * height; i++) { if (map[i] != null) { map[i].update(); } } } } public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; Texture2D tile; StarWars starwars; const int tile_size = 4; public Game1() { graphics = new GraphicsDeviceManager(this); } protected override void Initialize() { int w = 800 / tile_size, h = 600 / tile_size; starwars = new StarWars(w, h); for (int i = 0; i < w*h;i++) starwars.make(i); base.Initialize(); } protected override void LoadGraphicsContent(bool loadAllContent) { if (loadAllContent) { tile = init_tile(); } } Texture2D init_tile() { Color[] image = new Color[tile_size * tile_size]; for (uint i = 0; i < tile_size * tile_size; i++) image[i] = Color.White; Texture2D t = new Texture2D(graphics.GraphicsDevice, tile_size, tile_size, 1, ResourceUsage.Tiled, SurfaceFormat.Color); t.SetData(image); return t; } void put_tile(SpriteBatch batch, int x, int y, Color c) { batch.Draw(tile, new Vector2(x*tile_size, y*tile_size), c); } protected override void Draw(GameTime gameTime) { graphics.GraphicsDevice.Clear(Color.CornflowerBlue); SpriteBatch spriteBatch = new SpriteBatch(graphics.GraphicsDevice); spriteBatch.Begin(); starwars.update(); for (int i = 0; i < starwars.width * starwars.height; i++) { Cell c = starwars.get(i); if (c == null) continue; Color cl = new Color[] { Color.Black, Color.Orange, Color.OrangeRed, Color.Red }[c.state]; put_tile(spriteBatch, c.x, c.y, cl); } spriteBatch.End(); base.Draw(gameTime); } } static class Program { static void Main(string[] args) { using (Game1 game = new Game1()) { game.Run(); } } } }