2014年12月21日 星期日

(教學)Visual C++ 2005程式設計: 如何應用Auto Number Generator現有的程式碼做出機台計算程式

Auto Number Generator Electronic List應用方式說明(ANGEL機台計算程式)
詹宗運製作
版本:Visual C++ 2005以上都可以使用

許多網友問為甚麼使用舊版2005版的Visual C++,
這是因為2005以上的VC++具備有版本轉換功能,
只要是2005版以上都可以順利轉換到最新版本的程式碼。

自動號碼產生器是一項超越時代的程式,
這裡A4element已經完全電腦化,
不需要用紙,不需要人力,也不需要印表機。
想想看可以在工業界節省多少費用。
為了要應用這一個好用的程式碼,
筆者特別開發了幾個範例程式,
比如說這兩天比較多人討論的自動加工廠問題,
可以利用這個產生器做初步的路線計算跟評估,
非常方便。
這裡要感謝這一段期間對筆者程式提出建議的網友,
你們改正了我程式中許多不成熟的敘述。
歡迎各種公司行號利用本程式所提到的程式技術,
應用開發更高層次工業化的程式,
拼經濟救台灣。


使用方式:
1.
使用Visual C++ 2005建立一個WIN32主控台應用程式,
命名為"ANG_Example03",
這時候編譯器會自動生成空白檔案"ANG_Example03.cpp"和正常的"stdafx.h",
並且新增一個空白標頭檔,名為
"arrays.h"
然後把下面相同名稱的"ANG_Example03.cpp"和"arrays.h"的檔案內容,
拷貝貼上到相同名稱的空白檔案裡面。

並且要整理程式碼換行的部份,
讓不該換行的程式碼不要換行,
就可以讓程式碼正確執行了。

2.新增程式碼部份
#define DELAYTIME 1500
這裡定義了每次顯示自動加工廠數字的間隔時間,
預設值1500是1.5秒的間隔。
如果調大這個數字就可以讓畫面更換的比較慢一點。

3.預設參數可以計算1到10的自動加工廠路線數量,
最大值雖然可以調整到10,但是數字會跳的非常慢,
可能要好幾個星期才會顯示完。
使用路線數字10的時候第10號自動加工廠路線會以0號路線顯示。
如果要增加到10以上的數字就要加大switch case敘述,
工作量其實是非常龐大的,
提供給各位做為參考。

SOLUTION的數字必須符合階乘的計算。
5! = 120
6! = 720
7! =5040
8! = 40320
9! =362880
10! = 3628800

//如果要計算5條自動加工廠路線請修改參數如下:
//-------------------------------
#define MAXQUEEN 5
#define TRUE 1
#define FALSE 0
#define SOLUTION 120//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE 6//ARRAYSIZE = MAXQUEEN+1




//如果要計算6條自動加工廠路線請修改參數如下:
//-------------------------------
#define MAXQUEEN 6
#define TRUE 1
#define FALSE 0
#define SOLUTION 720//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE 7//ARRAYSIZE = MAXQUEEN+1




//如果要計算7條自動加工廠路線請修改參數如下:
//-------------------------------
#define MAXQUEEN 7
#define TRUE 1
#define FALSE 0
#define SOLUTION 5040//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE 8//ARRAYSIZE = MAXQUEEN+1




//如果要計算8條自動加工廠路線請修改參數如下:
//-------------------------------
#define MAXQUEEN 8
#define TRUE 1
#define FALSE 0
#define SOLUTION 40320//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE 9//ARRAYSIZE = MAXQUEEN+1




//如果要計算9條自動加工廠路線請修改參數如下:
//-------------------------------
#define MAXQUEEN 9
#define TRUE 1
#define FALSE 0
#define SOLUTION 362880//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE 10//ARRAYSIZE = MAXQUEEN+1




//如果要計算10條自動加工廠路線請修改參數如下:
//-------------------------------
#define MAXQUEEN 10
#define TRUE 1
#define FALSE 0
#define SOLUTION 3628800//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE 11//ARRAYSIZE = MAXQUEEN+1
//-------------------------------
//-------------------------------



//以下是ANG_Example03.cpp程式碼
//---------------------------------------------
// ANG_Example03.cpp : 定義主控台應用程式的進入點。
//

//Auto Number Generator
//ANG_Example03.cpp
//by 詹宗運
//這是一個修改ANG_Prototype的範例,
//用來計算自動加工廠的重新最佳化與分流問題的一個計算程式。
//免費授權Microsoft公司進行進一步的修改與工業化
//用來攤平記憶體缺損所造成的工業損失
//並且提供VC++社群做為討論與修改的使用
//version: Visual C++ 2005

#include "stdafx.h"
#include "arrays.h"
typedef struct a4element
{
int identity;
int a_content[3];
} A4element;



#include <windows.h>//myerrorhandler
#include <stdarg.h>//myerrorhandler
#include <stdio.h>//cout
#include <rtcapi.h>//myerrorhandler

#include <ostream>//fopen


#include <stdlib.h>//calloc
#include <iostream>//cout
#include <iomanip>//setw()






#include <fstream>
#include <memory.h>//typeinfo
#include <typeinfo>//typeinfo
#include <string.h>//string
#include <cstring>//string
#include <cstddef>//string


//新增這一行
#define DELAYTIME 1500  //定義每次顯示自動加工廠生產線機台要間隔多少毫秒



#define MAXQUEEN 5//定義最大堆疊容量,如果要超過10請修改switch case敘述
#define TRUE 1
#define FALSE 0
#define SOLUTION 120//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE 6//ARRAYSIZE = MAXQUEEN+1
using namespace std;
int queen[MAXQUEEN];//存放8個皇后之列位置
int number=0;//計算總共有幾組解的總數
//決定皇后存放的位置
//輸出所需要的結果
#include "arrays.h"
UnorderedArray<int> array(4);




int SNum[SOLUTION][MAXQUEEN];//SNum = SolutionNumber
char SChar[SOLUTION][MAXQUEEN];//SChar = SolutionChar
char buf[SOLUTION*MAXQUEEN];//buf = bufferNumber

int remain;//remain = remain number

int calculate(int ,int);

#pragma runtime_checks("", off)

void print_table()
{
     int x=0,y=0;
     number+=1;


remain = SOLUTION-number;

     cout<<"自動產生"<<MAXQUEEN<<"個號碼組合的第"<<\
setw(7)<<number<<"組號碼,";
cout<<"進度為剩下"<<remain<<"組尚未處理。"<<endl<<"\t";



int k=0;
for(x=0;x<MAXQUEEN;x++)
     {
        for(y=0;y<MAXQUEEN;y++)
           if(x==queen[y])
  {
k=y+1;
  array.push(k);
  }

     }


}



void decide_position(int value)
{
   int i=0;// i=行
   while(i<MAXQUEEN)
   {
   //是否受到攻擊的判斷式
      if(calculate(i,value)!=TRUE)
      {
         queen[value]=i;//只有在未受攻擊時將計算值存入皇后陣列

         if(value==MAXQUEEN-1)//列已到末端
            print_table();//只有在未受攻擊時列已到末端時才印出結果
         else
            decide_position(value+1);//只有在未受攻擊時將計算值存入皇后陣列,
//計算完成以後,列+1遞迴重新執行函數( value=列)
      }
 //受攻擊時值不能存入陣列
      i++;//不論是否遭受攻擊都換行重新執行函數 i=行
   }  
}
//0,0 i++
//1,0 queen[0]=1
//1,1 flag=1,i++
//2,1 queen[1]=2
//2,2 flag=1,i++



//測試在(row,col)上的皇后是否遭受攻擊
//若遭受攻擊則傳回值為1,否則傳回0
int calculate(int row,int col)
{
    int i=0,flag=FALSE;
    //int offset_row=0,offset_col=0;
    while((flag!=TRUE)&&i<col)//當未遭受攻擊與i計算值小於VALUE
    {
       //offset_col=abs(i-col);
       //offset_row=abs(queen[i]-row);
       //判斷兩皇后是否在同一列在同一對角線上
       //if((queen[i]==row)||(offset_row==offset_col))
       if((queen[i]==row))//
 //不要在此輸入cout<<"queen["<<i<<"]=="<<row<<endl;
  flag=TRUE;//只有在未受攻擊與計算值小於VALUE,
//當皇后陣列與待求VALUE相同時,判定遭受攻擊
       i++;//逐行檢查
    }
    return flag;
}

#pragma runtime_checks("", off)
//主程式
void construct_A4element(){

int f=0;
int g=0;
int h=0;

remain=0;


A4element *a=(A4element*)calloc(SOLUTION,sizeof(A4element));

while(f<SOLUTION)
{


while(g<(ARRAYSIZE-1))
{
a->identity=f;
a->a_content[g]=array[h];

cout<<"目前核對a["<<f<<"]->a_content["<<g<<"]="<<\
(a->a_content[g])<<endl;//顯示內容

SNum[f][g]=array[h];

//如果要超過10階乘就要加大下面這個switch case敘述
switch(SNum[f][g])
{
case 10:
SChar[f][g]='0';
break;
case 1:
SChar[f][g]='1';
break;
case 2:
SChar[f][g]='2';
break;
case 3:
SChar[f][g]='3';
break;
case 4:
SChar[f][g]='4';
break;
case 5:
SChar[f][g]='5';
break;
case 6:
SChar[f][g]='6';
break;
case 7:
SChar[f][g]='7';
break;
case 8:
SChar[f][g]='8';
break;
case 9:
SChar[f][g]='9';
break;

}


buf[h]=SChar[f][g];

h++;
g++;
}
g=0;
f++;
remain=SOLUTION - f;
cout<<"核對資料結構還剩下"<<remain<<"組。"<<endl;

}

cout<<"計算完成"<<endl;
system("pause");

//----------------------------------------------------------------------
//string str(SOLUTION*MAXQUEEN,' ');

cout<<"號碼產生的數量是 "<<h<<"個。"<<endl;
cout<<"自動號碼產生器的自動加工廠生產線機台\
路線計算程式已經計算完成。"<<endl;
cout<<"請按下按鍵顯示結果。"<<endl;
system("pause");


//--------------------------------------------------------
//-------------make SNum----------------------------------

//cout<<"計算SNum當中"<<endl;
int m=0;
int n=0;
int p=0;
    remain=0;

while(m<SOLUTION)
{
while(n<MAXQUEEN)
{
a->identity=m;
a->a_content[n]=array[p];

//cout << "核對SNum[" <<m<< "]["<< n <<"]="<<(SNum[m][n])<<endl;
//cout << "核對SChar["<<m<<"]["<<n<<"]="<<(SChar[m][n])<<endl;

SNum[m][n]=a->a_content[n];




p++;

n++;
}
n=0;
//---遞迴顯示自動號碼----

system("CLS");
cout<<"自動加工廠生產線機台路線計算程式:"<<endl;
cout<<"生產線機台組合第"<<(m+1)<<"組的組合是:  首先,"<<endl;
for(int t=0;t<MAXQUEEN;t++)
cout<<"將半成品輸送到生產線第"<<SChar[m][t]<<"號機台。接下來,"<<endl;
cout<<"就完成了半成品的加工。"<<endl;
//-----------------------
m++;
remain=SOLUTION-m;

cout<<"以上是自動加工廠機台組合的第"<<m<<\
"組的組合,剩下"<<remain<<"組"<<endl;
cout<<"請參考自動加工廠的生產線位置圖做進一步設計。";
//system("pause");
Sleep(DELAYTIME);
}

cout<<"以上是自動號碼產生器實作,"<<endl;



//取消了輸出檔案的功能

cout<<"array的型態 = "<<typeid(array).name()<<endl;
cout<<"感謝Allen Sherrod先生的資料結構教科書,僅此致謝。"<<endl;
cout<<"Auto Number Generator: Visual C++ 2005版,"<<endl;
cout<<"詹宗運製作,"<<endl;
cout<<"免費授權Microsoft公司進行進一步的修改與工業化,"<<endl;
cout<<"用來攤平記憶體缺損所造成的工業損失,"<<endl;
cout<<"並且提供VC++社群做為討論與修改的使用。"<<endl;
system("pause");
free(a);

}




//主程式


#pragma runtime_checks("", off)

// RTC Error Handler
int MyErrorHandler(int errType, const char* file, int line,
    const char* module, const char* format, ...)
{
    // 1. Prevent re-entrance
    static long IsRunning = 0;
    while ( InterlockedExchange(&IsRunning, 1) )
        Sleep(1);

    // 2. Get the RTC error number from the var_arg list
    va_list ArgList;
    va_start(ArgList, format);
    _RTC_ErrorNumber ErrorNumber = va_arg(ArgList, _RTC_ErrorNumber);
    va_end(ArgList);

    char s[1024];
    // 3. Get the error description
    const char* ErrorDesc = _RTC_GetErrDesc(ErrorNumber);
    sprintf_s(s, sizeof(s), "%s occured.\nLine: %i\
\nFile: %s\nModule: %s\nClick OK to break into debugger.",\
  ErrorDesc, line, file ? file :\

"Unknown",    module ? module : "Unknown");
 
// 4. Display message box
    MessageBoxA(NULL, s, "Run-Time Error", MB_OK);
    // 5. Go ahead and break into the debugger
    return 1;
}
#pragma runtime_checks("", restore)




int _tmain(int argc, _TCHAR* argv[])
{


cout<<"自動號碼生成器應用:自動加工廠生產線機台路線計算程式,"<<endl;
cout<<"詹宗運製作。"<<endl;
cout<<"接下來會自動運算出許多訊息,請耐心等待訊息停止以後,"<<endl;
cout<<"再按下按鍵繼續運算。"<<endl;
cout<<"開始運算,請準備。"<<endl;
system("pause");

    cout<<"\t";



    _RTC_error_fn OldHandler;
    // Set new RTC error handler and save the old one
    OldHandler = _RTC_SetErrorFunc(&MyErrorHandler);



decide_position(0);
construct_A4element();

    _RTC_SetErrorFunc(OldHandler);
system("pause");


return 0;
}



//---------------------------------------------
//程式碼到此為止

//以下是arrays.h程式碼
//---------------------------------------------
/*
   Array Data Structure
   Chapter 2
   Data Structures for Game Developers
   Created by Allen Sherrod
*/


#include<cassert>


#ifndef _ARRAYS_H_
#define _ARRAYS_H_


template<typename T>
class UnorderedArray
{
   public:
      UnorderedArray(int size, int growBy = 1) :
                     m_array(NULL), m_maxSize(0),
                     m_growSize(0), m_numElements(0)
      {
         if(size)
            {
               m_maxSize = size;
               m_array = new T[m_maxSize];
               memset(m_array, 0, sizeof(T) * m_maxSize);

               m_growSize = ((growBy > 0) ? growBy : 0);
            }
      }

      ~UnorderedArray()
      {
         if(m_array != NULL)
            {
               delete[] m_array;
               m_array = NULL;
            }
      }

      void push(T val)
      {
         assert(m_array != NULL);

         if(m_numElements >= m_maxSize)
            {
               Expand();
            }

         m_array[m_numElements] = val;
         m_numElements++;
      }

      void pop()
      {
         if(m_numElements > 0)
            m_numElements--;
      }

      void remove(int index)
      {
         assert(m_array != NULL);

         if(index >= m_maxSize)
            {
               return;
            }

         for(int k = index; k < m_maxSize - 1; k++)
            m_array[k] = m_array[k + 1];
   
         m_maxSize--;

         if(m_numElements >= m_maxSize)
            m_numElements = m_maxSize - 1;
      }

      T& operator[](int index)
      {
         assert(m_array != NULL && index <= m_numElements);
         return m_array[index];
      }

      int search(T val)
      {
         assert(m_array != NULL);

         for(int i = 0; i < m_numElements; i++)
            {
               if(m_array[i] == val)
                  return i;
            }

         return -1;
      }

      void clear()      { m_numElements = 0; }
      int GetSize()     { return m_numElements; }
      int GetMaxSize()  { return m_maxSize; }
      int GetGrowSize() { return m_growSize; }

      void SetGrowSize(int val)
      {
         assert(val >= 0);
         m_growSize = val;
      }

   private:
      bool Expand()
      {
         if(m_growSize <= 0)
            return false;

         T *temp = new T[m_maxSize + m_growSize];
         assert(temp != NULL);

         memcpy(temp, m_array, sizeof(T) * m_maxSize);

         delete[] m_array;
         m_array = temp;

         m_maxSize += m_growSize;

         return true;
      }

   private:
      T *m_array;

      int m_maxSize;
      int m_growSize;
      int m_numElements;
};


template <typename T>
class OrderedArray
{
   public:
      OrderedArray(int size, int growBy = 1) :
                   m_array(NULL), m_maxSize(0),
                   m_growSize(0), m_numElements(0)
      {
         if(size)
            {
               m_maxSize = size;
               m_array = new T[m_maxSize];
               memset(m_array, 0, sizeof(T) * m_maxSize);

               m_growSize = ((growBy > 0) ? growBy : 0);
            }
      }

      ~OrderedArray()
      {
         if(m_array != NULL)
            {
               delete[] m_array;
               m_array = NULL;
            }
      }

      int push(T val)
      {
         assert(m_array != NULL);

         if(m_numElements >= m_maxSize)
            {
               Expand();
            }

         int i, k;

         for(i = 0; i < m_numElements; i++)
            {
               if(m_array[i] > val)
                  break;
            }

         for(k = m_numElements; k > i; k--)
            {
               m_array[k] = m_array[k - 1];
            }

         m_array[i] = val;
         m_numElements++;

         return i;
      }

      void pop()
      {
         if(m_numElements > 0)
            m_numElements--;
      }

      void remove(int index)
      {
         assert(m_array != NULL);

         if(index >= m_maxSize)
            {
               return;
            }

         for(int k = index; k < m_maxSize - 1; k++)
            m_array[k] = m_array[k + 1];
   
         m_maxSize--;

         if(m_numElements >= m_maxSize)
            m_numElements = m_maxSize - 1;
      }

      // Making this const allows for reading but not writing.
      const T& operator[](int index)
      {
         assert(m_array != NULL && index <= m_numElements);
         return m_array[index];
      }

      int search(T searchKey)
      {
         assert(m_array != NULL);

         int lowerBound = 0;
         int upperBound = m_numElements - 1;
         int current = 0;

         while(1)
            {
               current = (lowerBound + upperBound) >> 1;
             
               if(m_array[current] == searchKey)
                  {
                     return current;
                  }
               else if(lowerBound > upperBound)
                  {
                     return -1;
                  }
               else
                  {
                     if(m_array[current] < searchKey)
                        lowerBound = current + 1;
                     else
                        upperBound = current - 1;
                  }
            }

         return -1;
      }

      void clear()      { m_numElements = 0; }
      int GetSize()     { return m_numElements; }
      int GetMaxSize()  { return m_maxSize; }
      int GetGrowSize() { return m_growSize; }

      void SetGrowSize(int val)
      {
         assert(val >= 0);
         m_growSize = val;
      }

   private:
      bool Expand()
      {
         if(m_growSize <= 0)
            return false;

         T *temp = new T[m_maxSize + m_growSize];
         assert(temp != NULL);

         memcpy(temp, m_array, sizeof(T) * m_maxSize);

         delete[] m_array;
         m_array = temp;

         m_maxSize += m_growSize;

         return true;
      }

   private:
      T *m_array;

      int m_maxSize;
      int m_growSize;
      int m_numElements;
};


#endif
//---------------------------------------------
//程式碼到此為止


//以下是stdafx.h程式碼
//---------------------------------------------
// stdafx.h : 可在此標頭檔中包含標準的系統 Include 檔,
// 或是經常使用卻很少變更的
// 專案專用 Include 檔案
//

#pragma once

#ifndef _WIN32_WINNT // 允許使用 Windows XP (含) 以後版本的特定功能。
#define _WIN32_WINNT 0x0501 // 將它變更為針對 Windows 其他版本的適當值。
#endif

#include <stdio.h>
#include <tchar.h>



// TODO: 在此參考您的程式所需要的其他標頭

//---------------------------------------------


2014年12月10日 星期三

(教學)Visual C++ 2005: 如何使用Auto Number Generator現有的程式碼(自動加工廠分流系統)

Auto Number Generator Electronic List應用方式說明
詹宗運製作
版本:Visual C++ 2005以上都可以使用

自動號碼產生器是一項超越時代的程式,
這裡A4element已經完全電腦化,
不需要用紙,不需要人力,也不需要印表機。
想想看可以在工業界節省多少費用。
為了要應用這一個好用的程式碼,
筆者特別開發了幾個範例程式,
比如說這兩天比較多人討論的自動加工廠問題,
可以利用這個產生器做初步的路線計算跟評估,
非常方便。
歡迎各種公司行號利用本程式所提到的程式技術,
應用開發更高層次工業化的程式,
拼經濟救台灣。


使用方式:
1.
使用Visual C++ 2005建立一個WIN32主控台應用程式,
命名為"ANG_Example02",
這時候編譯器會自動生成空白檔案"ANG_Example02.cpp"和正常的"stdafx.h",
並且新增一個空白標頭檔,名為
"arrays.h"
然後把下面相同名稱的"ANG_Example02.cpp"和"arrays.h"的檔案內容,
拷貝貼上到相同名稱的空白檔案裡面。

並且要整理程式碼換行的部份,
讓不該換行的程式碼不要換行,
就可以讓程式碼正確執行了。

2.新增程式碼部份
#define DELAYTIME 1500
這裡定義了每次顯示自動加工廠數字的間隔時間,
預設值1500是1.5秒的間隔。
如果調大這個數字就可以讓畫面更換的比較慢一點。

3.預設參數可以計算1到10的自動加工廠路線數量,
最大值雖然可以調整到10,但是數字會跳的非常慢,
可能要好幾個星期才會顯示完。
使用路線數字10的時候第10號自動加工廠路線會以0號路線顯示。
如果要增加到10以上的數字就要加大switch case敘述,
工作量其實是非常龐大的,
提供給各位做為參考。

SOLUTION的數字必須符合階乘的計算。
5! = 120
6! = 720
7! =5040
8! = 40320
9! =362880
10! = 3628800

//如果要計算5條自動加工廠路線請修改參數如下:
//-------------------------------
#define MAXQUEEN 5
#define TRUE 1
#define FALSE 0
#define SOLUTION 120//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE 6//ARRAYSIZE = MAXQUEEN+1




//如果要計算6條自動加工廠路線請修改參數如下:
//-------------------------------
#define MAXQUEEN 6
#define TRUE 1
#define FALSE 0
#define SOLUTION 720//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE 7//ARRAYSIZE = MAXQUEEN+1




//如果要計算7條自動加工廠路線請修改參數如下:
//-------------------------------
#define MAXQUEEN 7
#define TRUE 1
#define FALSE 0
#define SOLUTION 5040//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE 8//ARRAYSIZE = MAXQUEEN+1




//如果要計算8條自動加工廠路線請修改參數如下:
//-------------------------------
#define MAXQUEEN 8
#define TRUE 1
#define FALSE 0
#define SOLUTION 40320//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE 9//ARRAYSIZE = MAXQUEEN+1




//如果要計算9條自動加工廠路線請修改參數如下:
//-------------------------------
#define MAXQUEEN 9
#define TRUE 1
#define FALSE 0
#define SOLUTION 362880//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE 10//ARRAYSIZE = MAXQUEEN+1




//如果要計算10條自動加工廠路線請修改參數如下:
//-------------------------------
#define MAXQUEEN 10
#define TRUE 1
#define FALSE 0
#define SOLUTION 3628800//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE 11//ARRAYSIZE = MAXQUEEN+1
//-------------------------------
//-------------------------------


//下面是stdafx.h程式碼部份:
//-------------------------------
// stdafx.h : 可在此標頭檔中包含標準的系統 Include 檔,
// 或是經常使用卻很少變更的
// 專案專用 Include 檔案
//

#pragma once

#ifndef _WIN32_WINNT // 允許使用 Windows XP (含) 以後版本的特定功能。
#define _WIN32_WINNT 0x0501 // 將它變更為針對 Windows 其他版本的適當值。
#endif

#include <stdio.h>
#include <tchar.h>



// TODO: 在此參考您的程式所需要的其他標頭
//-------------------------------
//程式碼到此為止

//以下是arrays.h程式碼
//-------------------------------
/*
   Array Data Structure
   Chapter 2
   Data Structures for Game Developers
   Created by Allen Sherrod
*/


#include<cassert>


#ifndef _ARRAYS_H_
#define _ARRAYS_H_


template<typename T>
class UnorderedArray
{
   public:
      UnorderedArray(int size, int growBy = 1) :
                     m_array(NULL), m_maxSize(0),
                     m_growSize(0), m_numElements(0)
      {
         if(size)
            {
               m_maxSize = size;
               m_array = new T[m_maxSize];
               memset(m_array, 0, sizeof(T) * m_maxSize);

               m_growSize = ((growBy > 0) ? growBy : 0);
            }
      }

      ~UnorderedArray()
      {
         if(m_array != NULL)
            {
               delete[] m_array;
               m_array = NULL;
            }
      }

      void push(T val)
      {
         assert(m_array != NULL);

         if(m_numElements >= m_maxSize)
            {
               Expand();
            }

         m_array[m_numElements] = val;
         m_numElements++;
      }

      void pop()
      {
         if(m_numElements > 0)
            m_numElements--;
      }

      void remove(int index)
      {
         assert(m_array != NULL);

         if(index >= m_maxSize)
            {
               return;
            }

         for(int k = index; k < m_maxSize - 1; k++)
            m_array[k] = m_array[k + 1];
   
         m_maxSize--;

         if(m_numElements >= m_maxSize)
            m_numElements = m_maxSize - 1;
      }

      T& operator[](int index)
      {
         assert(m_array != NULL && index <= m_numElements);
         return m_array[index];
      }

      int search(T val)
      {
         assert(m_array != NULL);

         for(int i = 0; i < m_numElements; i++)
            {
               if(m_array[i] == val)
                  return i;
            }

         return -1;
      }

      void clear()      { m_numElements = 0; }
      int GetSize()     { return m_numElements; }
      int GetMaxSize()  { return m_maxSize; }
      int GetGrowSize() { return m_growSize; }

      void SetGrowSize(int val)
      {
         assert(val >= 0);
         m_growSize = val;
      }

   private:
      bool Expand()
      {
         if(m_growSize <= 0)
            return false;

         T *temp = new T[m_maxSize + m_growSize];
         assert(temp != NULL);

         memcpy(temp, m_array, sizeof(T) * m_maxSize);

         delete[] m_array;
         m_array = temp;

         m_maxSize += m_growSize;

         return true;
      }

   private:
      T *m_array;

      int m_maxSize;
      int m_growSize;
      int m_numElements;
};


template <typename T>
class OrderedArray
{
   public:
      OrderedArray(int size, int growBy = 1) :
                   m_array(NULL), m_maxSize(0),
                   m_growSize(0), m_numElements(0)
      {
         if(size)
            {
               m_maxSize = size;
               m_array = new T[m_maxSize];
               memset(m_array, 0, sizeof(T) * m_maxSize);

               m_growSize = ((growBy > 0) ? growBy : 0);
            }
      }

      ~OrderedArray()
      {
         if(m_array != NULL)
            {
               delete[] m_array;
               m_array = NULL;
            }
      }

      int push(T val)
      {
         assert(m_array != NULL);

         if(m_numElements >= m_maxSize)
            {
               Expand();
            }

         int i, k;

         for(i = 0; i < m_numElements; i++)
            {
               if(m_array[i] > val)
                  break;
            }

         for(k = m_numElements; k > i; k--)
            {
               m_array[k] = m_array[k - 1];
            }

         m_array[i] = val;
         m_numElements++;

         return i;
      }

      void pop()
      {
         if(m_numElements > 0)
            m_numElements--;
      }

      void remove(int index)
      {
         assert(m_array != NULL);

         if(index >= m_maxSize)
            {
               return;
            }

         for(int k = index; k < m_maxSize - 1; k++)
            m_array[k] = m_array[k + 1];
   
         m_maxSize--;

         if(m_numElements >= m_maxSize)
            m_numElements = m_maxSize - 1;
      }

      // Making this const allows for reading but not writing.
      const T& operator[](int index)
      {
         assert(m_array != NULL && index <= m_numElements);
         return m_array[index];
      }

      int search(T searchKey)
      {
         assert(m_array != NULL);

         int lowerBound = 0;
         int upperBound = m_numElements - 1;
         int current = 0;

         while(1)
            {
               current = (lowerBound + upperBound) >> 1;
             
               if(m_array[current] == searchKey)
                  {
                     return current;
                  }
               else if(lowerBound > upperBound)
                  {
                     return -1;
                  }
               else
                  {
                     if(m_array[current] < searchKey)
                        lowerBound = current + 1;
                     else
                        upperBound = current - 1;
                  }
            }

         return -1;
      }

      void clear()      { m_numElements = 0; }
      int GetSize()     { return m_numElements; }
      int GetMaxSize()  { return m_maxSize; }
      int GetGrowSize() { return m_growSize; }

      void SetGrowSize(int val)
      {
         assert(val >= 0);
         m_growSize = val;
      }

   private:
      bool Expand()
      {
         if(m_growSize <= 0)
            return false;

         T *temp = new T[m_maxSize + m_growSize];
         assert(temp != NULL);

         memcpy(temp, m_array, sizeof(T) * m_maxSize);

         delete[] m_array;
         m_array = temp;

         m_maxSize += m_growSize;

         return true;
      }

   private:
      T *m_array;

      int m_maxSize;
      int m_growSize;
      int m_numElements;
};


#endif
//-------------------------------
//程式碼到此為止

//以下是ANG_Example02.cpp程式碼部份:
//-------------------------------
// ANG_Example02.cpp : 定義主控台應用程式的進入點。
//
//Auto Number Generator
//ANG_Example02.cpp
//by 詹宗運
//這是一個修改ANG_Prototype的範例,
//用來計算自動加工廠的分流問題的一個計算程式。
//免費授權Microsoft公司進行進一步的修改與工業化
//用來攤平記憶體缺損所造成的工業損失
//並且提供VC++社群做為討論與修改的使用
//version: Visual C++ 2005

#include "stdafx.h"
#include "arrays.h"
typedef struct a4element
{
int identity;
int a_content[3];
} A4element;



#include <windows.h>//myerrorhandler
#include <stdarg.h>//myerrorhandler
#include <stdio.h>//cout
#include <rtcapi.h>//myerrorhandler

#include <ostream>//fopen


#include <stdlib.h>//calloc
#include <iostream>//cout
#include <iomanip>//setw()






#include <fstream>
#include <memory.h>//typeinfo
#include <typeinfo>//typeinfo
#include <string.h>//string
#include <cstring>//string
#include <cstddef>//string


//新增這一行
#define DELAYTIME 1500  //定義每次顯示自動加工廠生產線自動分流系統要間隔多少毫秒



#define MAXQUEEN 6//定義最大堆疊容量,如果要超過10請修改switch case敘述
#define TRUE 1
#define FALSE 0
#define SOLUTION 720//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE 7//ARRAYSIZE = MAXQUEEN+1
using namespace std;
int queen[MAXQUEEN];//存放8個皇后之列位置
int number=0;//計算總共有幾組解的總數
//決定皇后存放的位置
//輸出所需要的結果
#include "arrays.h"
UnorderedArray<int> array(4);




int SNum[SOLUTION][MAXQUEEN];//SNum = SolutionNumber
char SChar[SOLUTION][MAXQUEEN];//SChar = SolutionChar
char buf[SOLUTION*MAXQUEEN];//buf = bufferNumber

int remain;//remain = remain number

int calculate(int ,int);

#pragma runtime_checks("", off)

void print_table()
{
     int x=0,y=0;
     number+=1;


remain = SOLUTION-number;

     cout<<"自動產生"<<MAXQUEEN<<"個號碼組合的第"<<setw(7)<<number<<"組號碼,進度為剩下"<<remain<<"組尚未處理。"<<endl<<"\t";


int k=0;
for(x=0;x<MAXQUEEN;x++)
     {
        for(y=0;y<MAXQUEEN;y++)
           if(x==queen[y])
  {
k=y+1;
  array.push(k);
  }

     }


}



void decide_position(int value)
{
   int i=0;// i=行
   while(i<MAXQUEEN)
   {
   //是否受到攻擊的判斷式
      if(calculate(i,value)!=TRUE)
      {
         queen[value]=i;//只有在未受攻擊時將計算值存入皇后陣列

         if(value==MAXQUEEN-1)//列已到末端
            print_table();//只有在未受攻擊時列已到末端時才印出結果
         else
            decide_position(value+1);//只有在未受攻擊時將計算值存入皇后陣列,
//計算完成以後,列+1遞迴重新執行函數( value=列)
      }
 //受攻擊時值不能存入陣列
      i++;//不論是否遭受攻擊都換行重新執行函數 i=行
   }  
}
//0,0 i++
//1,0 queen[0]=1
//1,1 flag=1,i++
//2,1 queen[1]=2
//2,2 flag=1,i++



//測試在(row,col)上的皇后是否遭受攻擊
//若遭受攻擊則傳回值為1,否則傳回0
int calculate(int row,int col)
{
    int i=0,flag=FALSE;
    //int offset_row=0,offset_col=0;
    while((flag!=TRUE)&&i<col)//當未遭受攻擊與i計算值小於VALUE
    {
       //offset_col=abs(i-col);
       //offset_row=abs(queen[i]-row);
       //判斷兩皇后是否在同一列在同一對角線上
       //if((queen[i]==row)||(offset_row==offset_col))
       if((queen[i]==row))//
 //不要在此輸入cout<<"queen["<<i<<"]=="<<row<<endl;
  flag=TRUE;//只有在未受攻擊與計算值小於VALUE,
//當皇后陣列與待求VALUE相同時,判定遭受攻擊
       i++;//逐行檢查
    }
    return flag;
}

#pragma runtime_checks("", off)
//主程式
void construct_A4element(){

int f=0;
int g=0;
int h=0;

remain=0;


A4element *a=(A4element*)calloc(SOLUTION,sizeof(A4element));

while(f<SOLUTION)
{


while(g<(ARRAYSIZE-1))
{
a->identity=f;
a->a_content[g]=array[h];

cout<<"目前核對a["<<f<<"]->a_content["<<g<<"]="<<\
(a->a_content[g])<<endl;//顯示內容

SNum[f][g]=array[h];

//如果要超過10階乘就要加大下面這個switch case敘述
switch(SNum[f][g])
{
case 10:
SChar[f][g]='0';
break;
case 1:
SChar[f][g]='1';
break;
case 2:
SChar[f][g]='2';
break;
case 3:
SChar[f][g]='3';
break;
case 4:
SChar[f][g]='4';
break;
case 5:
SChar[f][g]='5';
break;
case 6:
SChar[f][g]='6';
break;
case 7:
SChar[f][g]='7';
break;
case 8:
SChar[f][g]='8';
break;
case 9:
SChar[f][g]='9';
break;

}


buf[h]=SChar[f][g];

h++;
g++;
}
g=0;
f++;
remain=SOLUTION - f;
cout<<"核對資料結構還剩下"<<remain<<"組。"<<endl;

}

cout<<"計算完成"<<endl;
system("pause");

//----------------------------------------------------------------------------

//string str(SOLUTION*MAXQUEEN,' ');

cout<<"號碼產生的數量是 "<<h<<"個。"<<endl;
cout<<"自動號碼產生器的自動加工廠生產線自動分流系統\
已經計算完成。請按下按鍵顯示結果。"<<endl;
system("pause");


//--------------------------------------------------------
//-------------make SNum----------------------------------

//cout<<"計算SNum當中"<<endl;
int m=0;
int n=0;
int p=0;
    remain=0;

while(m<SOLUTION)
{
while(n<MAXQUEEN)
{
a->identity=m;
a->a_content[n]=array[p];

//cout << "核對SNum[" <<m<< "]["<< n <<"]="<<(SNum[m][n])<<endl;
//cout << "核對SChar["<<m<<"]["<<n<<"]="<<(SChar[m][n])<<endl;

SNum[m][n]=a->a_content[n];




p++;

n++;
}
n=0;
//---遞迴顯示自動號碼----

system("CLS");
cout<<"自動加工廠生產線自動分流系統:"<<endl;
cout<<"第"<<(m+1)<<"組生產線組合是:  首先,"<<endl;
for(int t=0;t<MAXQUEEN;t++)
cout<<"將半成品輸送到第"<<SChar[m][t]<<"號生產線。接下來,"<<endl;
cout<<"就完成了半成品的加工。"<<endl;
//-----------------------
m++;
remain=SOLUTION-m;

cout<<"以上是自動加工廠分流系統的第"<<m<<\
"組的組合,剩下"<<remain<<"組"<<endl;
cout<<"請參考自動加工廠的生產線位置圖做進一步設計。";
//system("pause");
Sleep(DELAYTIME);
}

cout<<"以上是自動號碼產生器實作,"<<endl;



//取消了輸出檔案的功能

cout<<"array的型態 = "<<typeid(array).name()<<endl;
cout<<"感謝Allen Sherrod先生的資料結構教科書,僅此致謝。"<<endl;
cout<<"Auto Number Generator: Visual C++ 2005版,"<<endl;
cout<<"詹宗運製作,"<<endl;
cout<<"免費授權Microsoft公司進行進一步的修改與工業化,"<<endl;
cout<<"用來攤平記憶體缺損所造成的工業損失,"<<endl;
cout<<"並且提供VC++社群做為討論與修改的使用。"<<endl;
system("pause");
free(a);

}




//主程式


#pragma runtime_checks("", off)

// RTC Error Handler
int MyErrorHandler(int errType, const char* file, int line,
    const char* module, const char* format, ...)
{
    // 1. Prevent re-entrance
    static long IsRunning = 0;
    while ( InterlockedExchange(&IsRunning, 1) )
        Sleep(1);

    // 2. Get the RTC error number from the var_arg list
    va_list ArgList;
    va_start(ArgList, format);
    _RTC_ErrorNumber ErrorNumber = va_arg(ArgList, _RTC_ErrorNumber);
    va_end(ArgList);

    char s[1024];
    // 3. Get the error description
    const char* ErrorDesc = _RTC_GetErrDesc(ErrorNumber);
    sprintf_s(s, sizeof(s), "%s occured.\nLine: %i\
\nFile: %s\nModule: %s\nClick OK to break into debugger.",\
      ErrorDesc, line, file ? file :\

"Unknown",    module ? module : "Unknown");
 
// 4. Display message box
    MessageBoxA(NULL, s, "Run-Time Error", MB_OK);
    // 5. Go ahead and break into the debugger
    return 1;
}
#pragma runtime_checks("", restore)




int _tmain(int argc, _TCHAR* argv[])
{


cout<<"自動號碼生成器應用:自動加工廠生產線自動分流系統,詹宗運製作。"<<endl;
cout<<"接下來會自動運算出許多訊息,請耐心等待訊息停止以後,"<<endl;
cout<<"再按下按鍵繼續運算。"<<endl;
cout<<"開始運算,請準備。"<<endl;
system("pause");

    cout<<"\t";



_RTC_error_fn OldHandler;
    // Set new RTC error handler and save the old one
    OldHandler = _RTC_SetErrorFunc(&MyErrorHandler);



decide_position(0);
construct_A4element();

    _RTC_SetErrorFunc(OldHandler);
system("pause");


return 0;
}

//程式碼到此為止

2014年12月8日 星期一

(教學)Visual C++ 2005程式設計:如何應用Auto Number Generator現有的程式碼

Auto Number Generator Electronic List應用方式說明
詹宗運製作
版本:Visual C++ 2017配合Windows 10 SDK使用

自動號碼產生器是一項超越時代的程式,
這裡A4element已經完全電腦化,
不需要用紙,不需要人力,也不需要印表機。
想想看可以在工業界節省多少費用。
為了要應用這一個好用的程式碼,
筆者特別開發了幾個範例程式,
比如說這兩天比較多人討論的捷運站問題,
可以利用這個產生器做初步的路線計算跟評估,
非常方便。
歡迎各種公司行號利用本程式所提到的程式技術,
應用開發更高層次工業化的程式,
拼經濟救台灣。


使用方式:
1.
使用Visual C++ 2017建立一個WIN32主控台應用程式,
命名為"ANG_Example01",
這時候編譯器會自動生成空白檔案"ANG_Example01.cpp",
和正常的"stdafx.h"和"targetver.h",
並且新增一個空白標頭檔,名為
"arrays.h"
然後把下面相同名稱的"ANG_Example01.cpp"和"arrays.h"的檔案內容,
拷貝貼上到相同名稱的空白檔案裡面。

並且要整理程式碼換行的部份,
讓不該換行的程式碼不要換行,
就可以讓程式碼正確執行了。

2.新增程式碼部份
DELAYTIME = speedswitch();
這裡定義了每次顯示捷運站數字的間隔時間,
慢速是1500毫秒是1.5秒的間隔。
如果選擇慢速就可以讓畫面更換的比較慢一點。

3.預設參數可以計算1到10的捷運路線數量,
最大值雖然可以調整到10,但是數字會跳的非常慢,
可能要好幾個星期才會顯示完。
如果要增加到10以上的數字就要加大switch case敘述,
工作量其實是非常龐大的,
提供給各位做為參考。

SOLUTION的數字必須符合階乘的計算。
5! = 120
6! = 720
7! =5040
8! = 40320
9! =362880
10! = 3628800

//如果要計算5條捷運路線請修改參數如下:
//-------------------------------
#define MAXQUEEN 5
#define TRUE 1
#define FALSE 0
#define SOLUTION 120//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE1 6//ARRAYSIZE1 = MAXQUEEN+1




//如果要計算6條捷運路線請修改參數如下:
//-------------------------------
#define MAXQUEEN 6
#define TRUE 1
#define FALSE 0
#define SOLUTION 720//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE1 7//ARRAYSIZE1 = MAXQUEEN+1




//如果要計算7條捷運路線請修改參數如下:
//-------------------------------
#define MAXQUEEN 7
#define TRUE 1
#define FALSE 0
#define SOLUTION 5040//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE1 8//ARRAYSIZE1 = MAXQUEEN+1




//如果要計算8條捷運路線請修改參數如下:
//-------------------------------
#define MAXQUEEN 8
#define TRUE 1
#define FALSE 0
#define SOLUTION 40320//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE1 9//ARRAYSIZE1 = MAXQUEEN+1




//如果要計算9條捷運路線請修改參數如下:
//-------------------------------
#define MAXQUEEN 9
#define TRUE 1
#define FALSE 0
#define SOLUTION 362880//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE1 10//ARRAYSIZE1 = MAXQUEEN+1




//如果要計算10條捷運路線請修改參數如下:
//-------------------------------
#define MAXQUEEN 10
#define TRUE 1
#define FALSE 0
#define SOLUTION 3628800//SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE1 11//ARRAYSIZE1 = MAXQUEEN+1
//-------------------------------
//-------------------------------









//以下是ANG_Example01.cpp程式碼部份:
//-------------------------------
//版本: 適用於Visual C++ 2017 與 Windows 10
//Windows 10 必須安裝Windows 10 SDK才能編譯這個程式。

// ANG_Example01.cpp : 定義主控台應用程式的進入點。
//Auto Number Generator
//ANG_Example01.cpp
//by 詹宗運
//這是一個修改ANG_Prototype的範例,
//用來計算台北市目前正在討論的捷運路線問題。
//免費授權Microsoft公司進行進一步的修改與工業化
//用來攤平記憶體缺損所造成的工業損失
//並且提供VC++社群做為討論與修改的使用
//version: Visual C++ 2017 版本:20180322新版




#include "stdafx.h"



//這裡是改數字的主要區域
/*可以透過改變數字來計算更多的排列組合*/

#define MAXQUEEN 5    //定義最大堆疊容量,如果要超過10請修改switch case敘述
#define TRUE 1
#define FALSE 0
#define SOLUTION 120   //SOLUTION = (MAXQUEEN)! 例如5!=120, 3!=6,4!=24,7! = 5040
#define ARRAYSIZE1 6    //ARRAYSIZE1 = MAXQUEEN+1
#define SLOTNUMBER 10  //一共有10個欄位


//以上是改數字的主要區域
//可以透過改變數字來計算更多的排列組合
//用來運算的結構,可以想成是一疊計算紙
typedef struct a4element

{

int identity;

int a_content[3];

} A4element;

//儲存時間名稱的結構
struct time_slot
{
int id;
const char* name;
};


//儲存路線名稱的結構
struct show_slot
{
int id;
const char* name;
};


#include <windows.h>//myerrorhandler
#include <stdarg.h>//myerrorhandler
#include <stdio.h>//cout
#include <rtcapi.h>//myerrorhandler
#include <ostream>//fopen
#include <stdlib.h>//calloc
#include <iostream>//cout
#include <iomanip>//setw()
#include <fstream>
#include <memory.h>//typeinfo
#include <typeinfo>//typeinfo
#include <string.h>//string
#include <cstring>//string
#include <cstddef>//string



using namespace std;

int queen[MAXQUEEN];//存放8個皇后之列位置

int number = 0;//計算總共有幾組解的總數

   //決定皇后存放的位置

   //輸出所需要的結果

#include "arrays.h"

UnorderedArray<int> array01(4);


//新增這一行


int DELAYTIME;//暫停多少毫秒

int SNum[SOLUTION][MAXQUEEN];//SNum = SolutionNumber
char SChar[SOLUTION][MAXQUEEN];//SChar = SolutionChar
char buf[SOLUTION*MAXQUEEN];//buf = bufferNumber

int remain;//remain = remain number

int calculate(int, int);

#pragma runtime_checks("", off)

void print_table()

{
//遞迴運算式,建議不要更改參數
int x = 0, y = 0;
number += 1;
remain = SOLUTION - number;



cout << "自動產生" << MAXQUEEN << "個號碼組合的第" << setw(7) << number;
cout << "組號碼,進度為剩下" << remain << "組尚未處理。" << endl << "\t";

system("CLS");

int k = 0;

for (x = 0; x<MAXQUEEN; x++)
{
for (y = 0; y<MAXQUEEN; y++)
if (x == queen[y])
{
k = y + 1;
array01.push(k);
}
}
}






//遞迴運算式,建議不要更改參數
//資料來源:金禾資訊 吳燦銘先生 資料結構使用C++
//ISBN:9789861492575

void decide_position(int value)

{

int i = 0;// i=行

while (i<MAXQUEEN)
{
//是否受到攻擊的判斷式
if (calculate(i, value) != TRUE)
{
queen[value] = i;//只有在未受攻擊時將計算值存入皇后陣列
if (value == MAXQUEEN - 1)//列已到末端
print_table();//只有在未受攻擊時列已到末端時才印出結果
else
decide_position(value + 1);//只有在未受攻擊時將計算值存入皇后陣列,
//計算完成以後,列+1遞迴重新執行函數( value=列)
}

//受攻擊時值不能存入陣列

i++;//不論是否遭受攻擊都換行重新執行函數 i=行
}
}

//0,0 i++
//1,0 queen[0]=1
//1,1 flag=1,i++
//2,1 queen[1]=2
//2,2 flag=1,i++


//遞迴運算式,建議不要更改參數
//測試在(row,col)上的皇后是否遭受攻擊
//若遭受攻擊則傳回值為1,否則傳回0
//資料來源:金禾資訊 吳燦銘先生 資料結構使用C++
//ISBN:9789861492575


int calculate(int row, int col)

{

int i = 0, flag = FALSE;

//int offset_row=0,offset_col=0;//此行跳過不用

while ((flag != TRUE) && i<col)//當未遭受攻擊與i計算值小於VALUE
{

//offset_col=abs(i-col);//此行跳過不用
//offset_row=abs(queen[i]-row);//此行跳過不用
//判斷兩皇后是否在同一列在同一對角線上
//if((queen[i]==row)||(offset_row==offset_col))//此行跳過不用
if ((queen[i] == row))//
flag = TRUE;//只有在未受攻擊與計算值小於VALUE,
//當皇后陣列與待求VALUE相同時,判定遭受攻擊

i++;//逐行檢查

}

return flag;

}

#pragma runtime_checks("", off)
//選擇播放速度

int speedswitch()

{
char b;
while (1)
{
system("CLS");
cout << "請按下數字鍵,選擇播放速度:" << endl;
cout << "1.慢速  2.快速  0.繼續  請選擇(0-2):";
cin.get(b);

switch (b)
{
case '1':
cout << endl;
cout << "已選擇慢速播放。" << endl;
return 1500;
break;

case '2':
cout << endl;
cout << "已選擇快速播放。" << endl;
return 10;
break;

case '0':
goto Here;

}
}
Here:

return 10;
}




#pragma runtime_checks("", off)

//主程式

void construct_A4element() {

//定義結構名稱

time_slot t_slot[SLOTNUMBER - 1];
for (int i = 0; i<(SLOTNUMBER - 1); i++)
{
t_slot[i].id = i;
}

t_slot[0].name = "六點三十分";
t_slot[1].name = "六點五十分";
t_slot[2].name = "七點一十分";
t_slot[3].name = "七點三十分";
t_slot[4].name = "七點五十分";
t_slot[5].name = "八點一十分";
t_slot[6].name = "八點三十分";
t_slot[7].name = "八點五十分";
t_slot[8].name = "九點";
// t_slot[9].name = "九點三十分";


show_slot s_slot[SLOTNUMBER - 1];

for (int i = 0; i<(SLOTNUMBER - 1); i++)
{
s_slot[i].id = i;
}

s_slot[0].name = "中和新蘆線";
s_slot[1].name = "捷運板南線";
s_slot[2].name = "捷運文湖線";
s_slot[3].name = "淡水信義線";
s_slot[4].name = "松山新店線";
s_slot[5].name = "六號捷運線";
s_slot[6].name = "七號捷運線";
s_slot[7].name = "八號捷運線";
s_slot[8].name = "九號捷運線";
// s_slot[9].name = "十號捷運線";



//開始遞迴運算
int f = 0;

int g = 0;

int h = 0;



remain = 0;





A4element *a = (A4element*)calloc(SOLUTION, sizeof(A4element));



while (f<SOLUTION)

{





while (g<(ARRAYSIZE1 - 1))

{

a->identity = f;

a->a_content[g] = array01[h];



//cout<<"目前核對a["<<f<<"]->a_content["<<g<<"]="<<(a->a_content[g])<<endl;//顯示內容



SNum[f][g] = array01[h];



//如果要超過10階乘就要加大下面這個switch case敘述

switch (SNum[f][g])

{

case 10:

SChar[f][g] = '0';

break;

case 1:

SChar[f][g] = '1';

break;

case 2:

SChar[f][g] = '2';

break;

case 3:

SChar[f][g] = '3';

break;

case 4:

SChar[f][g] = '4';

break;

case 5:

SChar[f][g] = '5';

break;

case 6:

SChar[f][g] = '6';

break;

case 7:

SChar[f][g] = '7';

break;

case 8:

SChar[f][g] = '8';

break;

case 9:

SChar[f][g] = '9';

break;



}





buf[h] = SChar[f][g];



h++;

g++;

}

g = 0;

f++;

remain = SOLUTION - f;

cout << "核對資料結構還剩下" << remain << "組。" << endl;
system("CLS");


}



cout << "計算完成" << endl;

//----------------------------------------------------------------------------
//string str(SOLUTION*MAXQUEEN,' ');



cout << "號碼產生的數量是 " << h << "個。" << endl;
cout << "接下來你可以按下數字鍵加上ENTER鍵選擇播放速度," << endl;
cout << "自動號碼產生器已經計算完成。請按下按鍵顯示結果。" << endl;
system("pause");

//--------------------------------------------------------
//切換速度

DELAYTIME = speedswitch();//切換速度

  //--------------------------------------------------------

  //-------------make SNum----------------------------------



  //cout<<"計算SNum當中"<<endl;

int m = 0;

int n = 0;

int p = 0;

remain = 0;



while (m<SOLUTION)

{

while (n<MAXQUEEN)

{

a->identity = m;

a->a_content[n] = array01[p];

SNum[m][n] = a->a_content[n];

p++;

n++;

}

n = 0;

//---遞迴顯示自動號碼----



system("CLS");
cout << "搭捷運到基隆的捷運路線排列組合產生器:" << endl;
cout << "第" << (m + 1) << "組捷運路線組合是:   首先," << endl;

for (int i2 = 0; i2<MAXQUEEN; i2++) {

cout << "在" << t_slot[i2].name << "的時候,向";
cout << s_slot[SNum[m][i2] - 1].name << "移動,並且搭上捷運。接下來," << endl;
}

cout << "最後搭乘上基隆線的捷運," << endl;
cout << "就完成了所有路線的搭乘並且到達了基隆。" << endl;
//-----------------------

m++;

remain = SOLUTION - m;

cout << "以上是捷運路線的第" << m << "組的組合,剩下" << remain << "組。" << endl;
cout << "捷運路線是否為有效路線,請參考捷運路線圖。";

Sleep(DELAYTIME);

}


cout << "以上是自動號碼產生器實作," << endl;

//取消了輸出檔案的功能

cout << "array的型態 = " << typeid(array01).name() << endl;
cout << "感謝Allen Sherrod的資料結構教科書,僅此致謝。" << endl;
cout << "Auto Number Generator: Visual C++ 2017版," << endl;
cout << "詹宗運製作," << endl;
cout << "免費授權Microsoft公司進行進一步的修改與工業化," << endl;
cout << "用來攤平記憶體缺損所造成的工業損失," << endl;
cout << "並且提供VC++社群做為討論與修改的使用。" << endl;

system("pause");

//將共用變數進行釋放與歸零
// free(a);
memset(&a, NULL, sizeof(&a));
a = NULL;
free(a);

memset(&SNum, NULL, sizeof(&SNum));
for (int i = 0; i<SOLUTION; i++)
{

for (int j = 0; j < (ARRAYSIZE1 - 1); j++)
{

SNum[i][j] = NULL;

}
}

//delete *SNum;   //不刪除變數可以避免return引起的問題

memset(&SChar, NULL, sizeof(&SChar));

for (int i = 0; i<SOLUTION; i++)
{
for (int j = 0; j < (ARRAYSIZE1 - 1); j++)
{
SChar[i][j] = NULL;
}
}

//delete *SChar;   //不刪除變數可以避免return引起的問題

f = NULL;
g = NULL;
h = NULL;
remain = NULL;
m = NULL;
n = NULL;
p = NULL;

// delete t_slot;    //不刪除變數可以避免return引起的問題
// delete s_slot;



//直接結束關閉,此技術可以避免return引起的問題。
//exit(1);     //有需要時可以使用這一行程式碼。

//return;     //取消可以避免return引起的問題。

}

//主程式

#pragma runtime_checks("", off)

// RTC Error Handler

int MyErrorHandler(int errType, const char* file, int line,
const char* module, const char* format, ...)
{
// 1. Prevent re-entrance
static long IsRunning = 0;
while (InterlockedExchange(&IsRunning, 1))
Sleep(1);

// 2. Get the RTC error number from the var_arg list
va_list ArgList;
va_start(ArgList, format);
_RTC_ErrorNumber ErrorNumber = va_arg(ArgList, _RTC_ErrorNumber);
va_end(ArgList);

char s[1024];
// 3. Get the error description
const char* ErrorDesc = _RTC_GetErrDesc(ErrorNumber);
sprintf_s(s, sizeof(s), "%s occured.\nLine: %i\
        \nFile: %s\nModule:\
        %s\nClick OK to break into debugger.", \
ErrorDesc, line, file ? file : \
"Unknown", module ? module : "Unknown");




// 4. Display message box

MessageBoxA(NULL, s, "Run-Time Error", MB_OK);

// 5. Go ahead and break into the debugger

return 1;

}

#pragma runtime_checks("", restore)



void startmessage() {

cout << "自動號碼生成器應用:捷運路線排列組合產生器,詹宗運製作。" << endl;
cout << "接下來會自動運算出許多訊息,請耐心等待訊息停止以後," << endl;
cout << "再按下按鍵繼續運算。" << endl;
cout << "開始運算,請準備。" << endl;
system("pause");
cout << "\t";

}






int main()
{

//關掉.NET錯誤
_RTC_error_fn OldHandler;

// Set new RTC error handler and save the old one
OldHandler = _RTC_SetErrorFunc(&MyErrorHandler);

//顯示起始畫面訊息
startmessage();

//主程式
decide_position(0);

//主程式
construct_A4element();

//恢復.NET運作
_RTC_SetErrorFunc(OldHandler);

//直接結束關閉,此技術可以避免return引起的問題。
exit(1);

return EXIT_SUCCESS;     //出現了return可能會引起debugger中斷的問題

}

//-------------------------------

//程式碼到此為止
//-------------------------------


// TODO: 在此參考您的程式所需要的其他標頭
//以下是stdafx.h檔案
//-------------------------------
// stdafx.h : 可在此標頭檔中包含標準的系統 Include 檔,
// 或是經常使用卻很少變更的
// 專案專用 Include 檔案
//

#pragma once

#include "targetver.h"

#include <stdio.h>
#include <tchar.h>

//---stdafx.h檔案到此為止
//-------------------------------

// TODO:  在此參考您的程式所需要的其他標頭

//-------------------------------
//-----以下是targetver.h程式碼-----

#pragma once

// 加上 SDKDDKVer.h 可定義最高可用的 Windows 平台。

// 如果要針對先前的 Windows 平台建置應用程式,請加上 WinSDKVer.h,
// 並在加上 SDKDDKVer.h 之前將 _WIN32_WINNT 巨集設為要支援的平台。

#include <SDKDDKVer.h>


//以下是arrays.h程式碼
//-------------------------------
/*
   Array Data Structure
   Chapter 2
   Data Structures for Game Developers
   Created by Allen Sherrod
*/


#include<cassert>


#ifndef _ARRAYS_H_
#define _ARRAYS_H_


template<typename T>
class UnorderedArray
{
   public:
      UnorderedArray(int size, int growBy = 1) :
                     m_array(NULL), m_maxSize(0),
                     m_growSize(0), m_numElements(0)
      {
         if(size)
            {
               m_maxSize = size;
               m_array = new T[m_maxSize];
               memset(m_array, 0, sizeof(T) * m_maxSize);

               m_growSize = ((growBy > 0) ? growBy : 0);
            }
      }

      ~UnorderedArray()
      {
         if(m_array != NULL)
            {
               delete[] m_array;
               m_array = NULL;
            }
      }

      void push(T val)
      {
         assert(m_array != NULL);

         if(m_numElements >= m_maxSize)
            {
               Expand();
            }

         m_array[m_numElements] = val;
         m_numElements++;
      }

      void pop()
      {
         if(m_numElements > 0)
            m_numElements--;
      }

      void remove(int index)
      {
         assert(m_array != NULL);

         if(index >= m_maxSize)
            {
               return;
            }

         for(int k = index; k < m_maxSize - 1; k++)
            m_array[k] = m_array[k + 1];
   
         m_maxSize--;

         if(m_numElements >= m_maxSize)
            m_numElements = m_maxSize - 1;
      }

      T& operator[](int index)
      {
         assert(m_array != NULL && index <= m_numElements);
         return m_array[index];
      }

      int search(T val)
      {
         assert(m_array != NULL);

         for(int i = 0; i < m_numElements; i++)
            {
               if(m_array[i] == val)
                  return i;
            }

         return -1;
      }

      void clear()      { m_numElements = 0; }
      int GetSize()     { return m_numElements; }
      int GetMaxSize()  { return m_maxSize; }
      int GetGrowSize() { return m_growSize; }

      void SetGrowSize(int val)
      {
         assert(val >= 0);
         m_growSize = val;
      }

   private:
      bool Expand()
      {
         if(m_growSize <= 0)
            return false;

         T *temp = new T[m_maxSize + m_growSize];
         assert(temp != NULL);

         memcpy(temp, m_array, sizeof(T) * m_maxSize);

         delete[] m_array;
         m_array = temp;

         m_maxSize += m_growSize;

         return true;
      }

   private:
      T *m_array;

      int m_maxSize;
      int m_growSize;
      int m_numElements;
};


template <typename T>
class OrderedArray
{
   public:
      OrderedArray(int size, int growBy = 1) :
                   m_array(NULL), m_maxSize(0),
                   m_growSize(0), m_numElements(0)
      {
         if(size)
            {
               m_maxSize = size;
               m_array = new T[m_maxSize];
               memset(m_array, 0, sizeof(T) * m_maxSize);

               m_growSize = ((growBy > 0) ? growBy : 0);
            }
      }

      ~OrderedArray()
      {
         if(m_array != NULL)
            {
               delete[] m_array;
               m_array = NULL;
            }
      }

      int push(T val)
      {
         assert(m_array != NULL);

         if(m_numElements >= m_maxSize)
            {
               Expand();
            }

         int i, k;

         for(i = 0; i < m_numElements; i++)
            {
               if(m_array[i] > val)
                  break;
            }

         for(k = m_numElements; k > i; k--)
            {
               m_array[k] = m_array[k - 1];
            }

         m_array[i] = val;
         m_numElements++;

         return i;
      }

      void pop()
      {
         if(m_numElements > 0)
            m_numElements--;
      }

      void remove(int index)
      {
         assert(m_array != NULL);

         if(index >= m_maxSize)
            {
               return;
            }

         for(int k = index; k < m_maxSize - 1; k++)
            m_array[k] = m_array[k + 1];
   
         m_maxSize--;

         if(m_numElements >= m_maxSize)
            m_numElements = m_maxSize - 1;
      }

      // Making this const allows for reading but not writing.
      const T& operator[](int index)
      {
         assert(m_array != NULL && index <= m_numElements);
         return m_array[index];
      }

      int search(T searchKey)
      {
         assert(m_array != NULL);

         int lowerBound = 0;
         int upperBound = m_numElements - 1;
         int current = 0;

         while(1)
            {
               current = (lowerBound + upperBound) >> 1;
             
               if(m_array[current] == searchKey)
                  {
                     return current;
                  }
               else if(lowerBound > upperBound)
                  {
                     return -1;
                  }
               else
                  {
                     if(m_array[current] < searchKey)
                        lowerBound = current + 1;
                     else
                        upperBound = current - 1;
                  }
            }

         return -1;
      }

      void clear()      { m_numElements = 0; }
      int GetSize()     { return m_numElements; }
      int GetMaxSize()  { return m_maxSize; }
      int GetGrowSize() { return m_growSize; }

      void SetGrowSize(int val)
      {
         assert(val >= 0);
         m_growSize = val;
      }

   private:
      bool Expand()
      {
         if(m_growSize <= 0)
            return false;

         T *temp = new T[m_maxSize + m_growSize];
         assert(temp != NULL);

         memcpy(temp, m_array, sizeof(T) * m_maxSize);

         delete[] m_array;
         m_array = temp;

         m_maxSize += m_growSize;

         return true;
      }

   private:
      T *m_array;

      int m_maxSize;
      int m_growSize;
      int m_numElements;
};


#endif
//-------------------------------
//程式碼到此為止