锁拼图:一个困惑的难题(译文)
By robot-v1.0
本文链接 https://www.kyfws.com/games/lock-puzzle-a-perplexing-puzzle-zh/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 5 分钟阅读 - 2313 个词 阅读量 0锁拼图:一个困惑的难题(译文)
原文地址:https://www.codeproject.com/Articles/89155/Lock-Puzzle-A-Perplexing-Puzzle
原文作者:Christopher Denmark
译文由本站 robot-v1.0 翻译
前言
A brain melting puzzle in which you must turn several interconnected keys to unlock the solution
一个大脑融化难题,您必须转动几个相互关联的钥匙才能解锁解决方案
目录(Table of Contents)
介绍(Introduction)
该项目是一款危险上瘾且有些催眠的益智游戏,在该游戏中,玩家尝试将所有16个键都置于垂直位置.规则如下:(This project is a dangerously addictive and somewhat hypnotic puzzle game in which the player tries to situate all 16 keys to the vertical position. The rules are as follows:)
- 该锁有以4x4阵列排列的16个钥匙;每个键水平或垂直放置.(The lock has 16 keys arranged in a 4x4 array; each key oriented either horizontally or vertically.)
- 为了打开锁,所有钥匙必须垂直放置.(In order to open the lock, all the keys must be vertically oriented.)
- 当您将一个键转到另一个位置时,同一行和同一列中的所有其他键也会自动切换其位置.(When you turn a key to another position, all the other keys in the same row and column automatically switch their positions too.)
背景(Background)
在本文中,我希望展示如何创建一个基于数学问题的游戏,游戏名为" The Lock Problem". Paul Zeitz教授在他最近的系列讲座中提出了这个问题,题目是"数学解决问题的技巧",看到这个问题后,我受到启发,将其转换为使用C#的简单益智游戏.(In this article, I wish to show how to create a game derived from the mathematical problem named “The Lock Problem.” Professor Paul Zeitz presented this problem in his recent lecture series titled “The Art and Craft of Mathematical Problem Solving” and after seeing this problem, I became inspired to transform it into a simple puzzle game using C#.)
兴趣点(Points of Interest)
好吧,让我们首先组织我们的作品.该板有16个元素,分为四行四列.我们将如何安排所有内容,以便单击一个键也可以同时打开其他六个键?可能有几种方法可以做到这一点,但这就是我决定尝试的方法.我首先根据其在数组中的位置为4x4数组的每个元素分配数字ID.第一个数字代表行,第二个数字代表列.(Well, let us organize our pieces first. The board has 16 elements in four rows and four columns. How would we arrange everything so that clicking on one key also turns the other six respective keys? There may be several methods of achieving this but this is what I decided to try. I first assign each element of the 4x4 array with a numerical ID based on its position in the array. The first number represents the row and the second number represents the column.)
第一列第一行中的元素命名为L11,而第三列中第二个元素的命名为L32.让我们单击键L32.(The element in the first row of the first column is named L11, whereas, the second element in the third row is named L32. Let us click on key L32.)
我们的代码需要逐步浏览L11-L44中的元素列表,并找出哪些元素具有与单击的元素相对应的ID.对于L32,我们要查找任何以3开头或以2结尾的ID.(Our code needs to step through a list of elements from L11-L44 and find which ones have an ID that correspond with the clicked element. In the case of L32, we want to find any ID that begins with 3 OR ends with 2.)
这是查找和转动钥匙的主要方法.(Here is the main method for finding and turning the keys.)
private void ToggleKeyStates(object sender, EventArgs e)
{
// Get Sender cell coordinates and assign them to X and X char arrays
// This is the Key that was clicked
char[] XY = ((Key)sender).Name.ToCharArray(1, 2);
char X = XY[0];
char Y = XY[1];
// Using the clicked object as a reference,
// Cycle through controls and find the corresponding key objects
foreach (Key l in this.panel1.Controls)
{
// split the names of the key objects into char array
char[] xy = l.Name.ToCharArray(1, 2);
char x = xy[0];
char y = xy[1];
// Change state of rows and columns only
if (X == x || Y == y)
{
if(l.IsTurning == false)
l.TurnKey();
}
}
}
使用代码(Using the Code)
关于(A few words about the) Key
控制:它有两个(control: It has two) public
布尔属性名为(Boolean properties named) isTurning
和(and) isLocked
.的(. The) isTurning
属性告诉调用方法密钥在旋转过程中.的(property tells the calling method that the key is in the process of rotating. The) isLocked
财产,如果(property, if) true
,告诉调用方法该键处于水平锁定位置.(, tells the calling method that the key is in the horizontal locked position.)
public bool IsLocked
{
get{return m_isLocked;}
set {m_isLocked = value;}
}
public bool IsTurning
{
get{return m_isTurning;}
set{m_isTurning = value;}
}
锁定和解锁(Lock and Unlock)
当我们单击关键对象时,(When we click the key object, the) isTurning
和(and) isLocked
切换属性,启动计时器,并将键旋转设置为运动.计时器启用后会连续调用(properties are toggled, the timer starts, and the key rotation is set into motion. The timer, when enabled, continuously calls) DefinePositions()
它设置了位于12点,3点,6点或9点钟位置的线上最外侧点的限制.键旋转到水平或垂直位置,然后禁用计时器,旋转停止.(which sets the limits for the outermost points on the lines to situate in either the 12, 3, 6, or 9 o’clock positions. The key rotates to either a horizontal or a vertical position, the timer is then disabled and the rotation stops.)
private void DefinePositions()
{
// Rotate and stop at the 3, 6, 9, and 12 o'clock positions.
if (Degrees == 360)
{
Degrees = 0; // reset
this.timer1.Enabled = false; // stop timer
m_isTurning = !m_isTurning; // toggle turning flag
m_isLocked = false; // toggle locked flag
}
else if (Degrees == 90)
{
this.timer1.Enabled = false;
m_isTurning = !m_isTurning;
m_isLocked = true;
Degrees++;
}
else if (Degrees == 180)
{
this.timer1.Enabled = false;
m_isTurning = !m_isTurning;
m_isLocked = false;
Degrees++;
}
else if (Degrees == 270)
{
this.timer1.Enabled = false;
m_isTurning = !m_isTurning;
m_isLocked = true;
Degrees++;
}
else // keep moving and let us know that you are moving.
{
Degrees++;
m_isTurning = true;
}
// Update the form and controls.
this.Refresh();
}
遵循道路(Following the Path)
圆形路径的原点和曲面在(The origin and surface of the circular path are defined in the) DefineSurfacePath
方法.(method.)
private void DefineSurfacePath(out int x_center, out int y_center,
out float x_path, out float y_path, out float x_path2, out float y_path2)
{
int Radius = 30;
x_center = this.Width / 2;
y_center = this.Height / 2;
// define outer rotation path for first line
x_path = (GetCos(360 + Degrees + x_center + degreeOffset) * Radius) + x_center;
y_path = (GetSin(360 + Degrees + y_center + degreeOffset) * Radius) + y_center;
// define outer rotation path for second line
x_path2 = (GetCos(360 + Degrees + 180 + x_center + degreeOffset) * Radius) + x_center;
y_path2 = (GetSin(360 + Degrees + 180 + y_center + degreeOffset) * Radius) + y_center;
}
渲染图(Rendering)
的(The) OnPaint(PaintEventArgs e)
覆盖连续通话(override continuously calls) DrawKey(Graphics g)
.(.)
protected override void OnPaint(PaintEventArgs e)
{
// give .net the first try
base.OnPaint(e);
// then take over
Graphics g = e.Graphics;
DrawKey(g);
}
定义所有绘图点和位置后,(After all the Drawing Points and Positions are defined, the) DrawKey(Graphics g)
方法只是将给定值绘制到屏幕上.(method simply draws the given values to the screen.)
public void DrawKey(Graphics g)
{
// ake sure all graphics are smooth, not blocky.
g.SmoothingMode = SmoothingMode.AntiAlias;
g.CompositingQuality = CompositingQuality.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
// Declare Brush and pen objects
Brush brshREC = new SolidBrush(Color.White);
Pen p = new Pen(brshREC, 10);
// Declare radius and origin of circle
int x_center;
int y_center;
float x_path;
float y_path;
float x_path2;
float y_path2;
DefineSurfacePath(out x_center, out y_center, out x_path, out y_path,
out x_path2, out y_path2);
// draw previously defined points
g.DrawLine(p, x_center, y_center, x_path, y_path);
g.DrawLine(p, x_center, y_center, x_path2, y_path2);
}
历史(History)
- 2010年6月22日-第一版(06-22-2010 - First version)
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
C#4.0 C# .NET4 .NET Dev Design Architect 新闻 翻译